Java tutorial
/* * This file is part of The Technic Launcher Version 3. * Copyright (C) 2013 Syndicate, LLC * * The Technic Launcher is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * The Technic Launcher is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with the Technic Launcher. If not, see <http://www.gnu.org/licenses/>. */ package net.technicpack.launcher.ui; import net.technicpack.launcher.LauncherMain; import net.technicpack.launcher.settings.StartupParameters; import net.technicpack.launcher.ui.components.ModpackOptionsDialog; import net.technicpack.launchercore.install.LauncherDirectories; import net.technicpack.launchercore.modpacks.PackLoader; import net.technicpack.launchercore.modpacks.sources.IInstalledPackRepository; import net.technicpack.platform.io.PlatformPackInfo; import net.technicpack.rest.RestObject; import net.technicpack.ui.controls.DraggableFrame; import net.technicpack.ui.controls.LauncherDialog; import net.technicpack.ui.controls.RoundedButton; import net.technicpack.ui.controls.TintablePanel; import net.technicpack.ui.lang.IRelocalizableResource; import net.technicpack.ui.lang.ResourceLoader; import net.technicpack.launcher.launch.Installer; import net.technicpack.launcher.settings.TechnicSettings; import net.technicpack.launcher.ui.components.OptionsDialog; import net.technicpack.launcher.ui.components.discover.DiscoverInfoPanel; import net.technicpack.launcher.ui.components.modpacks.ModpackInfoPanel; import net.technicpack.launcher.ui.components.modpacks.ModpackSelector; import net.technicpack.launcher.ui.components.news.NewsInfoPanel; import net.technicpack.launcher.ui.components.news.NewsSelector; import net.technicpack.launcher.ui.controls.*; import net.technicpack.ui.controls.feeds.CountCircle; import net.technicpack.ui.controls.installation.ProgressBar; import net.technicpack.launchercore.auth.IAuthListener; import net.technicpack.launchercore.auth.IUserType; import net.technicpack.minecraftcore.mojang.auth.MojangUser; import net.technicpack.launchercore.auth.UserModel; import net.technicpack.launchercore.image.ImageRepository; import net.technicpack.launchercore.install.Version; import net.technicpack.launchercore.modpacks.InstalledPack; import net.technicpack.launchercore.modpacks.ModpackModel; import net.technicpack.platform.IPlatformApi; import net.technicpack.platform.io.AuthorshipInfo; import net.technicpack.utilslib.DesktopUtils; import net.technicpack.utilslib.PasteWatcher; import net.technicpack.utilslib.Utils; import org.apache.commons.io.FileUtils; import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.IOUtils; import javax.swing.*; import javax.swing.border.Border; import java.awt.*; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.Transferable; import java.awt.datatransfer.UnsupportedFlavorException; import java.awt.event.*; import java.io.File; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import java.util.concurrent.ExecutionException; import java.util.logging.Level; public class LauncherFrame extends DraggableFrame implements IRelocalizableResource, IAuthListener<MojangUser> { private static final int FRAME_WIDTH = 1194; private static final int FRAME_HEIGHT = 718; private static final int SIDEKICK_WIDTH = 300; private static final int SIDEKICK_HEIGHT = 250; public static final Color COLOR_RED = new Color(229, 0, 0); public static final Color COLOR_GREEN = new Color(90, 184, 96); public static final Color COLOR_BLUE = new Color(16, 108, 163); public static final Color COLOR_BLUE_DARKER = new Color(12, 94, 145); public static final Color COLOR_WHITE_TEXT = new Color(208, 208, 208); public static final Color COLOR_DIM_TEXT = new Color(160, 160, 160); public static final Color COLOR_HEADER_TEXT = new Color(255, 255, 255); public static final Color COLOR_CHARCOAL = new Color(31, 31, 31); public static final Color COLOR_BANNER = new Color(0, 0, 0, 160); public static final Color COLOR_PANEL = new Color(36, 38, 39); public static final Color COLOR_SCROLL_TRACK = new Color(18, 18, 18); public static final Color COLOR_SCROLL_THUMB = new Color(53, 53, 53); public static final Color COLOR_SELECTOR_BACK = new Color(22, 26, 29); public static final Color COLOR_FEED_BACK = new Color(22, 26, 29, 200); public static final Color COLOR_CENTRAL_BACK = new Color(25, 30, 34, 160); public static final Color COLOR_CENTRAL_BACK_OPAQUE = new Color(25, 30, 34); public static final Color COLOR_FEEDITEM_BACK = new Color(37, 44, 49); public static final Color COLOR_LIKES_BACK = new Color(20, 65, 97); public static final Color COLOR_BUTTON_BLUE = new Color(43, 128, 195); public static final Color COLOR_FORMELEMENT_INTERNAL = new Color(30, 39, 46); public static final Color COLOR_GREY_TEXT = new Color(86, 98, 110); public static final Color COLOR_FOOTER = new Color(27, 32, 36); public static final String TAB_DISCOVER = "discover"; public static final String TAB_MODPACKS = "modpacks"; public static final String TAB_NEWS = "news"; private ResourceLoader resources; private final UserModel<MojangUser> userModel; private final ImageRepository<IUserType> skinRepository; private final TechnicSettings settings; private final ImageRepository<ModpackModel> iconRepo; private final ImageRepository<ModpackModel> logoRepo; private final ImageRepository<ModpackModel> backgroundRepo; private final ImageRepository<AuthorshipInfo> avatarRepo; private final Installer installer; private final IPlatformApi platformApi; private final LauncherDirectories directories; private final IInstalledPackRepository packRepo; private final StartupParameters params; private ModpackOptionsDialog modpackOptionsDialog = null; private HeaderTab discoverTab; private HeaderTab modpacksTab; private HeaderTab newsTab; private CardLayout infoLayout; private JPanel infoSwap; private UserWidget userWidget; private ProgressBar installProgress; private Component installProgressPlaceholder; private RoundedButton playButton; private ModpackSelector modpackSelector; private NewsSelector newsSelector; private TintablePanel centralPanel; private TintablePanel footer; private String currentTabName; NewsInfoPanel newsInfoPanel; ModpackInfoPanel modpackPanel; DiscoverInfoPanel discoverInfoPanel; private PasteWatcher pasteWatcher = null; public LauncherFrame(final ResourceLoader resources, final ImageRepository<IUserType> skinRepository, final UserModel userModel, final TechnicSettings settings, final ModpackSelector modpackSelector, final ImageRepository<ModpackModel> iconRepo, final ImageRepository<ModpackModel> logoRepo, final ImageRepository<ModpackModel> backgroundRepo, final Installer installer, final ImageRepository<AuthorshipInfo> avatarRepo, final IPlatformApi platformApi, final LauncherDirectories directories, final IInstalledPackRepository packRepository, final StartupParameters params, final DiscoverInfoPanel discoverInfoPanel) { setSize(FRAME_WIDTH, FRAME_HEIGHT); setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); this.userModel = userModel; this.skinRepository = skinRepository; this.settings = settings; this.modpackSelector = modpackSelector; this.iconRepo = iconRepo; this.logoRepo = logoRepo; this.backgroundRepo = backgroundRepo; this.installer = installer; this.avatarRepo = avatarRepo; this.platformApi = platformApi; this.directories = directories; this.packRepo = packRepository; this.params = params; this.discoverInfoPanel = discoverInfoPanel; //Handles rebuilding the frame, so use it to build the frame in the first place relocalize(resources); selectTab("discover"); EventQueue.invokeLater(new Runnable() { @Override public void run() { LauncherMain.consoleFrame.setVisible(settings.getShowConsole()); } }); setLocationRelativeTo(null); } ///////////////////////////////////////////////// // Action responses ///////////////////////////////////////////////// protected void selectTab(String tabName) { discoverTab.setIsActive(false); modpacksTab.setIsActive(false); newsTab.setIsActive(false); if (tabName.equalsIgnoreCase(TAB_DISCOVER)) discoverTab.setIsActive(true); else if (tabName.equalsIgnoreCase(TAB_MODPACKS)) modpacksTab.setIsActive(true); else if (tabName.equalsIgnoreCase(TAB_NEWS)) { newsTab.setIsActive(true); newsSelector.ping(); } infoLayout.show(infoSwap, tabName); currentTabName = tabName; } protected void closeWindow() { System.exit(0); } protected void minimizeWindow() { this.setState(Frame.ICONIFIED); } protected void logout() { if (installer.isCurrentlyRunning()) return; userModel.setCurrentUser(null); } protected void launchModpack() { ModpackModel pack = modpackSelector.getSelectedPack(); boolean requiresInstall = false; if (pack == null || (pack.getInstalledPack() == null && (pack.getPackInfo() == null || !pack.getPackInfo().isComplete()))) return; if (pack.getInstalledDirectory() == null) { requiresInstall = true; pack.save(); modpackSelector.forceRefresh(); } if (requiresInstall) { try { if (pack.getPackInfo().shouldForceDirectory() && FilenameUtils.directoryContains(directories.getLauncherDirectory().getCanonicalPath(), pack.getInstalledDirectory().getCanonicalPath())) { JFileChooser chooser = new JFileChooser(directories.getLauncherDirectory()); chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); chooser.setCurrentDirectory(directories.getLauncherDirectory()); int result = chooser.showOpenDialog(this); if (result == JFileChooser.APPROVE_OPTION) { File file = chooser.getSelectedFile(); if (file.list().length > 0) { JOptionPane.showMessageDialog(this, resources.getString("modpackoptions.move.errortext"), resources.getString("modpackoptions.move.errortitle"), JOptionPane.WARNING_MESSAGE); return; } else if (FileUtils.directoryContains(directories.getLauncherDirectory(), file)) { JOptionPane.showMessageDialog(this, resources.getString("launcher.launch.requiresmove"), resources.getString("launcher.launch.requiretitle"), JOptionPane.WARNING_MESSAGE); return; } pack.setInstalledDirectory(file); } } } catch (IOException ex) { Utils.getLogger().log(Level.SEVERE, ex.getMessage(), ex); } } boolean forceInstall = false; Version installedVersion = pack.getInstalledVersion(); //Force a full install (check cache, redownload, unzip files) if we have no current installation of this modpack if (installedVersion == null) forceInstall = true; else if (pack.getBuild() != null && !pack.isLocalOnly()) { //Ask the user if they want to update to the newer version if: //1- the pack build is RECOMMENDED & the recommended version is diff from the installed version //2- the pack build is LATEST & the latest version is diff from the installed version //3- the pack build is neither LATEST or RECOMMENDED & the pack build is diff from the installed version boolean requestInstall = false; if (pack.getBuild().equalsIgnoreCase(InstalledPack.RECOMMENDED) && pack.getPackInfo().getRecommended() != null && !pack.getPackInfo().getRecommended().equalsIgnoreCase(installedVersion.getVersion())) requestInstall = true; else if (pack.getBuild().equalsIgnoreCase(InstalledPack.LATEST) && pack.getPackInfo().getLatest() != null && !pack.getPackInfo().getLatest().equalsIgnoreCase(installedVersion.getVersion())) requestInstall = true; else if (!pack.getBuild().equalsIgnoreCase(InstalledPack.RECOMMENDED) && !pack.getBuild().equalsIgnoreCase(InstalledPack.LATEST) && !pack.getBuild().equalsIgnoreCase(installedVersion.getVersion())) requestInstall = true; //If the user says yes, update, then force a full install if (requestInstall) { int result = JOptionPane.showConfirmDialog(this, resources.getString("launcher.install.query"), resources.getString("launcher.install.query.title"), JOptionPane.YES_NO_OPTION, JOptionPane.INFORMATION_MESSAGE); if (result == JOptionPane.YES_OPTION) { forceInstall = true; } } } //If we're forcing an install, then derive the installation build from the pack build //otherwise, just use the installed version String installBuild = null; if (forceInstall && !pack.isLocalOnly()) { installBuild = pack.getBuild(); if (installBuild.equalsIgnoreCase(InstalledPack.RECOMMENDED)) installBuild = pack.getPackInfo().getRecommended(); else if (installBuild.equalsIgnoreCase(InstalledPack.LATEST)) installBuild = pack.getPackInfo().getLatest(); } else installBuild = installedVersion.getVersion(); if (requiresInstall) { installer.justInstall(resources, pack, installBuild, forceInstall, this, installProgress); } else { installer.installAndRun(resources, pack, installBuild, forceInstall, this, installProgress); } installProgress.setVisible(true); installProgressPlaceholder.setVisible(false); userChanged(userModel.getCurrentUser()); invalidate(); } public void launchCompleted() { if (installer.isCurrentlyRunning()) { EventQueue.invokeLater(new Runnable() { @Override public void run() { launchCompleted(); } }); return; } installProgress.setVisible(false); installProgressPlaceholder.setVisible(true); userModel.setCurrentUser(userModel.getCurrentUser()); invalidate(); } protected void openModpackOptions(ModpackModel model) { if (modpackOptionsDialog == null) { centralPanel.setTintActive(true); footer.setTintActive(true); modpackOptionsDialog = new ModpackOptionsDialog(this, directories, model, resources); modpackOptionsDialog.setVisible(true); modpackOptionsDialog = null; centralPanel.setTintActive(false); footer.setTintActive(false); modpackPanel.setModpack(model); modpackSelector.forceRefresh(); } } protected void refreshModpackOptions(ModpackModel model) { if (modpackOptionsDialog != null) modpackOptionsDialog.refresh(model); } protected void openLauncherOptions() { centralPanel.setTintActive(true); footer.setTintActive(true); OptionsDialog dialog = new OptionsDialog(this, settings, resources, params); dialog.setVisible(true); centralPanel.setTintActive(false); footer.setTintActive(false); } ///////////////////////////////////////////////// // End Action responses ///////////////////////////////////////////////// private void initComponents() { BorderLayout layout = new BorderLayout(); setLayout(layout); ///////////////////////////////////////////////////////////// //HEADER ///////////////////////////////////////////////////////////// JPanel header = new JPanel(); header.setLayout(new BoxLayout(header, BoxLayout.LINE_AXIS)); header.setBackground(COLOR_BLUE); header.setForeground(COLOR_WHITE_TEXT); header.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 10)); this.add(header, BorderLayout.PAGE_START); ImageIcon headerIcon = resources.getIcon("platform_icon_title.png"); JButton headerLabel = new JButton(headerIcon); headerLabel.setBorder(BorderFactory.createEmptyBorder(5, 8, 5, 0)); headerLabel.setContentAreaFilled(false); headerLabel.setFocusPainted(false); headerLabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); headerLabel.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { DesktopUtils.browseUrl("http://beta.technicpack.net/"); } }); header.add(headerLabel); header.add(Box.createRigidArea(new Dimension(6, 0))); ActionListener tabListener = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { selectTab(e.getActionCommand()); } }; discoverTab = new HeaderTab(resources.getString("launcher.title.discover"), resources); header.add(discoverTab); discoverTab.setActionCommand(TAB_DISCOVER); discoverTab.addActionListener(tabListener); modpacksTab = new HeaderTab(resources.getString("launcher.title.modpacks"), resources); modpacksTab.setIsActive(true); modpacksTab.setHorizontalTextPosition(SwingConstants.LEADING); modpacksTab.addActionListener(tabListener); modpacksTab.setActionCommand(TAB_MODPACKS); header.add(modpacksTab); newsTab = new HeaderTab(resources.getString("launcher.title.news"), resources); newsTab.setLayout(null); newsTab.addActionListener(tabListener); newsTab.setActionCommand(TAB_NEWS); header.add(newsTab); CountCircle newsCircle = new CountCircle(); newsCircle.setBackground(COLOR_RED); newsCircle.setForeground(COLOR_WHITE_TEXT); newsCircle.setFont(resources.getFont(ResourceLoader.FONT_OPENSANS_BOLD, 14)); newsTab.add(newsCircle); newsCircle.setBounds(10, 17, 25, 25); header.add(Box.createHorizontalGlue()); JPanel rightHeaderPanel = new JPanel(); rightHeaderPanel.setOpaque(false); rightHeaderPanel.setLayout(new BoxLayout(rightHeaderPanel, BoxLayout.PAGE_AXIS)); rightHeaderPanel.setBorder(BorderFactory.createEmptyBorder(5, 0, 5, 0)); JPanel windowGadgetPanel = new JPanel(); windowGadgetPanel.setOpaque(false); windowGadgetPanel.setLayout(new BoxLayout(windowGadgetPanel, BoxLayout.LINE_AXIS)); windowGadgetPanel.setAlignmentX(RIGHT_ALIGNMENT); ImageIcon minimizeIcon = resources.getIcon("minimize.png"); JButton minimizeButton = new JButton(minimizeIcon); minimizeButton.setBorder(BorderFactory.createEmptyBorder()); minimizeButton.setContentAreaFilled(false); minimizeButton.setCursor(new Cursor(Cursor.HAND_CURSOR)); minimizeButton.setFocusable(false); minimizeButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { minimizeWindow(); } }); windowGadgetPanel.add(minimizeButton); ImageIcon closeIcon = resources.getIcon("close.png"); JButton closeButton = new JButton(closeIcon); closeButton.setBorder(BorderFactory.createEmptyBorder()); closeButton.setContentAreaFilled(false); closeButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { closeWindow(); } }); closeButton.setCursor(new Cursor(Cursor.HAND_CURSOR)); closeButton.setFocusable(false); windowGadgetPanel.add(closeButton); rightHeaderPanel.add(windowGadgetPanel); rightHeaderPanel.add(Box.createVerticalGlue()); JButton launcherOptionsLabel = new JButton(resources.getString("launcher.title.options")); launcherOptionsLabel.setIcon(resources.getIcon("options_cog.png")); launcherOptionsLabel.setFont(resources.getFont(ResourceLoader.FONT_RALEWAY, 14)); launcherOptionsLabel.setForeground(COLOR_WHITE_TEXT); launcherOptionsLabel.setHorizontalAlignment(SwingConstants.RIGHT); launcherOptionsLabel.setHorizontalTextPosition(SwingConstants.LEADING); launcherOptionsLabel.setAlignmentX(RIGHT_ALIGNMENT); launcherOptionsLabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); launcherOptionsLabel.setBorder(BorderFactory.createEmptyBorder()); launcherOptionsLabel.setContentAreaFilled(false); launcherOptionsLabel.setFocusPainted(false); launcherOptionsLabel.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { openLauncherOptions(); } }); rightHeaderPanel.add(launcherOptionsLabel); header.add(rightHeaderPanel); ///////////////////////////////////////////////////////////// // CENTRAL AREA ///////////////////////////////////////////////////////////// centralPanel = new TintablePanel(); centralPanel.setBackground(COLOR_CHARCOAL); centralPanel.setForeground(COLOR_WHITE_TEXT); centralPanel.setTintColor(COLOR_CENTRAL_BACK); this.add(centralPanel, BorderLayout.CENTER); centralPanel.setLayout(new BorderLayout()); modpackPanel = new ModpackInfoPanel(resources, iconRepo, logoRepo, backgroundRepo, avatarRepo, new ActionListener() { @Override public void actionPerformed(ActionEvent e) { openModpackOptions((ModpackModel) e.getSource()); } }, new ActionListener() { @Override public void actionPerformed(ActionEvent e) { refreshModpackOptions((ModpackModel) e.getSource()); } }); modpackSelector.setInfoPanel(modpackPanel); playButton = modpackPanel.getPlayButton(); playButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (e.getSource() instanceof ModpackModel) { setupPlayButtonText((ModpackModel) e.getSource(), userModel.getCurrentUser()); } else if (installer.isCurrentlyRunning()) { installer.cancel(); setupPlayButtonText(modpackSelector.getSelectedPack(), userModel.getCurrentUser()); } else { launchModpack(); } } }); modpackPanel.getDeleteButton().addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (JOptionPane.showConfirmDialog(LauncherFrame.this, resources.getString("modpackoptions.delete.confirmtext"), resources.getString("modpackoptions.delete.confirmtitle"), JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) { modpackSelector.getSelectedPack().delete(); modpackSelector.forceRefresh(); } } }); infoSwap = new JPanel(); infoLayout = new CardLayout(); infoSwap.setLayout(infoLayout); infoSwap.setOpaque(false); newsInfoPanel = new NewsInfoPanel(resources, avatarRepo); infoSwap.add(discoverInfoPanel, "discover"); JPanel newsHost = new JPanel(); infoSwap.add(newsHost, "news"); JPanel modpackHost = new JPanel(); infoSwap.add(modpackHost, "modpacks"); centralPanel.add(infoSwap, BorderLayout.CENTER); newsSelector = new NewsSelector(resources, newsInfoPanel, platformApi, avatarRepo, newsCircle, settings); newsHost.setLayout(new BorderLayout()); newsHost.add(newsInfoPanel, BorderLayout.CENTER); newsHost.add(newsSelector, BorderLayout.WEST); modpackHost.setLayout(new BorderLayout()); modpackHost.add(modpackPanel, BorderLayout.CENTER); modpackHost.add(modpackSelector, BorderLayout.WEST); footer = new TintablePanel(); footer.setTintColor(COLOR_CENTRAL_BACK); footer.setBackground(COLOR_FOOTER); footer.setLayout(new BoxLayout(footer, BoxLayout.LINE_AXIS)); footer.setForeground(COLOR_WHITE_TEXT); footer.setBorder(BorderFactory.createEmptyBorder(3, 6, 3, 12)); userWidget = new UserWidget(resources, skinRepository); userWidget.setMaximumSize(userWidget.getPreferredSize()); footer.add(userWidget); JLabel dashText = new JLabel("| "); dashText.setForeground(LauncherFrame.COLOR_WHITE_TEXT); dashText.setFont(resources.getFont(ResourceLoader.FONT_RALEWAY, 15)); footer.add(dashText); JButton logout = new JButton(resources.getString("launcher.user.logout")); logout.setBorder(BorderFactory.createEmptyBorder()); logout.setContentAreaFilled(false); logout.setFocusable(false); logout.setForeground(LauncherFrame.COLOR_WHITE_TEXT); logout.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); logout.setFont(resources.getFont(ResourceLoader.FONT_RALEWAY, 15)); logout.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { logout(); } }); footer.add(logout); installProgress = new ProgressBar(); installProgress.setForeground(Color.white); installProgress.setBackground(LauncherFrame.COLOR_GREEN); installProgress.setBorder(BorderFactory.createEmptyBorder(5, 45, 4, 45)); installProgress.setIcon(resources.getIcon("download_icon.png")); installProgress.setFont(resources.getFont(ResourceLoader.FONT_OPENSANS, 12)); installProgress.setVisible(false); footer.add(installProgress); installProgressPlaceholder = Box.createHorizontalGlue(); footer.add(installProgressPlaceholder); JLabel buildCtrl = new JLabel(resources.getString("launcher.build.text", resources.getLauncherBuild(), resources.getString("launcher.build." + settings.getBuildStream()))); buildCtrl.setForeground(COLOR_WHITE_TEXT); buildCtrl.setFont(resources.getFont(ResourceLoader.FONT_OPENSANS, 14)); buildCtrl.setHorizontalTextPosition(SwingConstants.RIGHT); buildCtrl.setHorizontalAlignment(SwingConstants.RIGHT); footer.add(buildCtrl); this.add(footer, BorderLayout.PAGE_END); } @Override public void relocalize(ResourceLoader loader) { this.resources = loader; this.resources.registerResource(this); setIconImage(this.resources.getImage("icon.png")); //Wipe controls this.getContentPane().removeAll(); this.setLayout(null); //Clear references to existing controls initComponents(); userChanged(userModel.getCurrentUser()); if (currentTabName != null) selectTab(currentTabName); EventQueue.invokeLater(new Runnable() { @Override public void run() { invalidate(); repaint(); } }); } @Override public void userChanged(MojangUser mojangUser) { if (mojangUser == null) this.setVisible(false); else { this.setVisible(true); userWidget.setUser(mojangUser); if (modpackSelector.getSelectedPack() != null) setupPlayButtonText(modpackSelector.getSelectedPack(), mojangUser); if (pasteWatcher == null) { pasteWatcher = new PasteWatcher(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { pasteUpdated((Transferable) e.getSource()); } }); } modpackSelector.forceRefresh(); EventQueue.invokeLater(new Runnable() { @Override public void run() { repaint(); } }); } } public void setupPlayButtonText(ModpackModel modpack, MojangUser user) { playButton.setEnabled(true); playButton.setForeground(LauncherFrame.COLOR_BUTTON_BLUE); if (installer.isCurrentlyRunning()) { playButton.setText(resources.getString("launcher.pack.cancel")); } else if (modpack.getInstalledVersion() != null) { if (userModel.getCurrentUser() == null || userModel.getCurrentUser().isOffline()) { playButton.setText(resources.getString("launcher.pack.launch.offline")); } else { playButton.setText(resources.getString("launcher.pack.launch")); } } else { if (userModel.getCurrentUser() == null || userModel.getCurrentUser().isOffline()) { playButton.setEnabled(false); playButton.setForeground(LauncherFrame.COLOR_GREY_TEXT); playButton.setText(resources.getString("launcher.pack.cannotinstall")); } else { playButton.setText(resources.getString("launcher.pack.install")); } } } protected void pasteUpdated(Transferable transferable) { String text; if (!transferable.isDataFlavorSupported(DataFlavor.stringFlavor)) return; try { text = transferable.getTransferData(DataFlavor.stringFlavor).toString(); } catch (IOException ex) { Utils.getLogger().log(Level.SEVERE, ex.getMessage(), ex); return; } catch (UnsupportedFlavorException ex) { Utils.getLogger().log(Level.SEVERE, ex.getMessage(), ex); return; } try { final URL platformUrl = new URL(text); new SwingWorker<PlatformPackInfo, Void>() { @Override protected PlatformPackInfo doInBackground() throws Exception { PlatformPackInfo info = RestObject.getRestObject(PlatformPackInfo.class, platformUrl.toString()); //Don't let people jerk us around with non-platform sites- make sure this is a real pack //on the technic platform return platformApi.getPlatformPackInfo(info.getName()); } @Override public void done() { PlatformPackInfo result; try { result = get(); if (result == null) return; } catch (ExecutionException ex) { //We eat these two exceptions because they are almost certainly caused by //the pasted text not being relevant to this program return; } catch (InterruptedException ex) { return; } if (!packRepo.getInstalledPacks().containsKey(result.getName())) { packRepo.put(new InstalledPack(result.getName(), true, InstalledPack.RECOMMENDED)); } packRepo.setSelectedSlug(result.getName()); modpackSelector.forceRefresh(); LauncherFrame.this.setExtendedState(JFrame.ICONIFIED); EventQueue.invokeLater(new Runnable() { @Override public void run() { LauncherFrame.this.setExtendedState(JFrame.NORMAL); EventQueue.invokeLater(new Runnable() { @Override public void run() { LauncherFrame.this.selectTab("modpacks"); } }); } }); } }.execute(); } catch (MalformedURLException ex) { return; } } }