diff --git a/launcher-fancy/src/main/java/com/skcraft/launcher/FancyLauncherFrame.java b/launcher-fancy/src/main/java/com/skcraft/launcher/FancyLauncherFrame.java index 0d413dd..7b1ea19 100644 --- a/launcher-fancy/src/main/java/com/skcraft/launcher/FancyLauncherFrame.java +++ b/launcher-fancy/src/main/java/com/skcraft/launcher/FancyLauncherFrame.java @@ -26,7 +26,7 @@ setSize(800, 500); setLocationRelativeTo(null); - SwingHelper.removeOpaqueness(getInstancesTable()); + SwingHelper.removeOpaqueness(getInstancesList()); SwingHelper.removeOpaqueness(getInstanceScroll()); getInstanceScroll().setBorder(BorderFactory.createEmptyBorder()); } diff --git a/launcher/src/main/java/com/skcraft/launcher/InstanceList.java b/launcher/src/main/java/com/skcraft/launcher/InstanceList.java index 8134b99..803320b 100644 --- a/launcher/src/main/java/com/skcraft/launcher/InstanceList.java +++ b/launcher/src/main/java/com/skcraft/launcher/InstanceList.java @@ -18,6 +18,7 @@ import lombok.extern.java.Log; import org.apache.commons.io.filefilter.DirectoryFileFilter; +import javax.swing.*; import java.io.File; import java.io.FileFilter; import java.io.IOException; @@ -33,7 +34,7 @@ * Stores the list of instances. */ @Log -public class InstanceList { +public class InstanceList extends AbstractListModel { private final Launcher launcher; @Getter private final List instances = new ArrayList(); @@ -97,6 +98,17 @@ */ public synchronized void sort() { Collections.sort(instances); + fireContentsChanged(this, 0, size()); + } + + @Override + public int getSize() { + return size(); + } + + @Override + public Instance getElementAt(int index) { + return get(index); } public final class Enumerator implements Callable, ProgressObservable { @@ -194,6 +206,7 @@ instances.clear(); instances.addAll(local); instances.addAll(remote); + fireContentsChanged(this, 0, size()); log.info(instances.size() + " instance(s) enumerated."); } diff --git a/launcher/src/main/java/com/skcraft/launcher/dialog/LauncherFrame.java b/launcher/src/main/java/com/skcraft/launcher/dialog/LauncherFrame.java index 1aa47b0..79f287d 100644 --- a/launcher/src/main/java/com/skcraft/launcher/dialog/LauncherFrame.java +++ b/launcher/src/main/java/com/skcraft/launcher/dialog/LauncherFrame.java @@ -10,10 +10,15 @@ import com.skcraft.launcher.Instance; import com.skcraft.launcher.InstanceList; import com.skcraft.launcher.Launcher; +import com.skcraft.launcher.dialog.renderer.InstanceCellRenderer; import com.skcraft.launcher.launch.LaunchListener; import com.skcraft.launcher.launch.LaunchOptions; import com.skcraft.launcher.launch.LaunchOptions.UpdatePolicy; -import com.skcraft.launcher.swing.*; +import com.skcraft.launcher.swing.ActionListeners; +import com.skcraft.launcher.swing.DoubleClickToButtonAdapter; +import com.skcraft.launcher.swing.PopupMouseAdapter; +import com.skcraft.launcher.swing.SwingHelper; +import com.skcraft.launcher.swing.WebpagePanel; import com.skcraft.launcher.util.SharedLocale; import com.skcraft.launcher.util.SwingExecutor; import lombok.Getter; @@ -22,8 +27,6 @@ import net.miginfocom.swing.MigLayout; import javax.swing.*; -import javax.swing.event.TableModelEvent; -import javax.swing.event.TableModelListener; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; @@ -43,11 +46,8 @@ private final Launcher launcher; - @Getter - private final InstanceTable instancesTable = new InstanceTable(); - private final InstanceTableModel instancesModel; - @Getter - private final JScrollPane instanceScroll = new JScrollPane(instancesTable); + @Getter private final JList instancesList = new JList(); + @Getter private final JScrollPane instanceScroll = new JScrollPane(instancesList); private WebpagePanel webView; private JSplitPane splitPane; private final JButton launchButton = new JButton(SharedLocale.tr("launcher.launch")); @@ -65,7 +65,6 @@ super(tr("launcher.title", launcher.getVersion())); this.launcher = launcher; - instancesModel = new InstanceTableModel(launcher.getInstances()); setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); setMinimumSize(new Dimension(400, 300)); @@ -102,7 +101,10 @@ }); updateCheck.setSelected(true); - instancesTable.setModel(instancesModel); + instancesList.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + instancesList.setDragEnabled(false); + instancesList.setCellRenderer(new InstanceCellRenderer()); + instancesList.setModel(launcher.getInstances()); launchButton.setFont(launchButton.getFont().deriveFont(Font.BOLD)); splitPane.setDividerLocation(200); splitPane.setDividerSize(4); @@ -117,16 +119,7 @@ add(container, BorderLayout.CENTER); - instancesModel.addTableModelListener(new TableModelListener() { - @Override - public void tableChanged(TableModelEvent e) { - if (instancesTable.getRowCount() > 0) { - instancesTable.setRowSelectionInterval(0, 0); - } - } - }); - - instancesTable.addMouseListener(new DoubleClickToButtonAdapter(launchButton)); + instancesList.addMouseListener(new DoubleClickToButtonAdapter(launchButton)); refreshButton.addActionListener(new ActionListener() { @Override @@ -157,16 +150,14 @@ } }); - instancesTable.addMouseListener(new PopupMouseAdapter() { + instancesList.addMouseListener(new PopupMouseAdapter() { @Override protected void showPopup(MouseEvent e) { - int index = instancesTable.rowAtPoint(e.getPoint()); - Instance selected = null; - if (index >= 0) { - instancesTable.setRowSelectionInterval(index, index); - selected = launcher.getInstances().get(index); + //noinspection unchecked + Instance selected = ((JList) e.getSource()).getSelectedValue(); + if (selected != null) { + popupInstanceMenu(e.getComponent(), e.getX(), e.getY(), selected); } - popupInstanceMenu(e.getComponent(), e.getX(), e.getY(), selected); } }); } @@ -249,7 +240,6 @@ public void actionPerformed(ActionEvent e) { selected.setUpdatePending(true); launch(); - instancesModel.update(); } }); popup.add(menuItem); @@ -319,7 +309,6 @@ @Override public void run() { launch(); - instancesModel.update(); } }, SwingExecutor.INSTANCE); } @@ -330,10 +319,6 @@ future.addListener(new Runnable() { @Override public void run() { - instancesModel.update(); - if (instancesTable.getRowCount() > 0) { - instancesTable.setRowSelectionInterval(0, 0); - } requestFocus(); } }, SwingExecutor.INSTANCE); @@ -349,7 +334,7 @@ private void launch() { boolean permitUpdate = updateCheck.isSelected(); - Instance instance = launcher.getInstances().get(instancesTable.getSelectedRow()); + Instance instance = instancesList.getSelectedValue(); LaunchOptions options = new LaunchOptions.Builder() .setInstance(instance) @@ -371,10 +356,6 @@ @Override public void instancesUpdated() { - LauncherFrame frame = frameRef.get(); - if (frame != null) { - frame.instancesModel.update(); - } } @Override diff --git a/launcher/src/main/java/com/skcraft/launcher/dialog/renderer/InstanceCellRenderer.java b/launcher/src/main/java/com/skcraft/launcher/dialog/renderer/InstanceCellRenderer.java new file mode 100644 index 0000000..344a3c5 --- /dev/null +++ b/launcher/src/main/java/com/skcraft/launcher/dialog/renderer/InstanceCellRenderer.java @@ -0,0 +1,48 @@ +/* + * SK's Minecraft Launcher + * Copyright (C) 2010-2014 Albert Pham and contributors + * Please see LICENSE.txt for license information. + */ + +package com.skcraft.launcher.dialog.renderer; + +import com.skcraft.launcher.Instance; +import com.skcraft.launcher.Launcher; +import com.skcraft.launcher.swing.SwingHelper; + +import javax.swing.*; +import java.awt.*; + +public class InstanceCellRenderer extends DefaultListCellRenderer { + + private final Icon instanceIcon; + private final Icon customInstanceIcon; + private final Icon downloadIcon; + + public InstanceCellRenderer() { + instanceIcon = SwingHelper.createIcon(Launcher.class, "instance_icon.png", 16, 16); + customInstanceIcon = SwingHelper.createIcon(Launcher.class, "custom_instance_icon.png", 16, 16); + downloadIcon = SwingHelper.createIcon(Launcher.class, "download_icon.png", 14, 14); + } + + @Override + public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { + Instance instance = (Instance) value; + JLabel label = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); + // Add some padding to the cell + label.setBorder(BorderFactory.createCompoundBorder(label.getBorder(), BorderFactory.createEmptyBorder(2, 4, 2, 4))); + label.setIcon(getInstanceIcon(instance)); + return label; + } + + private Icon getInstanceIcon(Instance instance) { + if (!instance.isLocal()) { + return downloadIcon; + } else if (instance.getManifestURL() != null) { + return instanceIcon; + } else { + return customInstanceIcon; + } + } + +} diff --git a/launcher/src/main/java/com/skcraft/launcher/swing/InstanceTable.java b/launcher/src/main/java/com/skcraft/launcher/swing/InstanceTable.java deleted file mode 100644 index 63643ed..0000000 --- a/launcher/src/main/java/com/skcraft/launcher/swing/InstanceTable.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * SK's Minecraft Launcher - * Copyright (C) 2010-2014 Albert Pham and contributors - * Please see LICENSE.txt for license information. - */ - -package com.skcraft.launcher.swing; - -import javax.swing.table.TableModel; - -public class InstanceTable extends DefaultTable { - - public InstanceTable() { - super(); - setTableHeader(null); - } - - @Override - public void setModel(TableModel dataModel) { - super.setModel(dataModel); - try { - getColumnModel().getColumn(0).setMaxWidth(24); - } catch (ArrayIndexOutOfBoundsException e) { - } - } -} diff --git a/launcher/src/main/java/com/skcraft/launcher/swing/InstanceTableModel.java b/launcher/src/main/java/com/skcraft/launcher/swing/InstanceTableModel.java deleted file mode 100644 index 583011d..0000000 --- a/launcher/src/main/java/com/skcraft/launcher/swing/InstanceTableModel.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * SK's Minecraft Launcher - * Copyright (C) 2010-2014 Albert Pham and contributors - * Please see LICENSE.txt for license information. - */ - -package com.skcraft.launcher.swing; - -import com.skcraft.launcher.Instance; -import com.skcraft.launcher.InstanceList; -import com.skcraft.launcher.Launcher; -import com.skcraft.launcher.util.SharedLocale; - -import javax.swing.*; -import javax.swing.table.AbstractTableModel; - -public class InstanceTableModel extends AbstractTableModel { - - private final InstanceList instances; - private final Icon instanceIcon; - private final Icon customInstanceIcon; - private final Icon downloadIcon; - - public InstanceTableModel(InstanceList instances) { - this.instances = instances; - instanceIcon = SwingHelper.createIcon(Launcher.class, "instance_icon.png", 16, 16); - customInstanceIcon = SwingHelper.createIcon(Launcher.class, "custom_instance_icon.png", 16, 16); - downloadIcon = SwingHelper.createIcon(Launcher.class, "download_icon.png", 14, 14); - } - - public void update() { - instances.sort(); - fireTableDataChanged(); - } - - @Override - public String getColumnName(int columnIndex) { - switch (columnIndex) { - case 0: - return ""; - case 1: - return SharedLocale.tr("launcher.modpackColumn"); - default: - return null; - } - } - - @Override - public Class getColumnClass(int columnIndex) { - switch (columnIndex) { - case 0: - return ImageIcon.class; - case 1: - return String.class; - default: - return null; - } - } - - @Override - public void setValueAt(Object value, int rowIndex, int columnIndex) { - switch (columnIndex) { - case 0: - instances.get(rowIndex).setSelected((boolean) (Boolean) value); - break; - case 1: - default: - break; - } - } - - @Override - public boolean isCellEditable(int rowIndex, int columnIndex) { - switch (columnIndex) { - case 0: - return false; - case 1: - return false; - default: - return false; - } - } - - @Override - public int getRowCount() { - return instances.size(); - } - - @Override - public int getColumnCount() { - return 2; - } - - @Override - public Object getValueAt(int rowIndex, int columnIndex) { - Instance instance; - switch (columnIndex) { - case 0: - instance = instances.get(rowIndex); - if (!instance.isLocal()) { - return downloadIcon; - } else if (instance.getManifestURL() != null) { - return instanceIcon; - } else { - return customInstanceIcon; - } - case 1: - instance = instances.get(rowIndex); - return instance.getTitle(); - default: - return null; - } - } - -}