/* * Copyright (C) 2007 TGMG <thegamemakerguru@gmail.com> * Copyright (C) 2007, 2008, 2010, 2011 IsmAvatar <IsmAvatar@gmail.com> * Copyright (C) 2007, 2008 Clam <clamisgood@gmail.com> * Copyright (C) 2007, 2008 Quadduc <quadduc@gmail.com> * Copyright (C) 2014, Robert B. Colton * * This file is part of LateralGM. * LateralGM is free software and comes with ABSOLUTELY NO WARRANTY. * See LICENSE for details. */ package org.lateralgm.subframes; import static java.lang.Integer.MAX_VALUE; import static javax.swing.GroupLayout.DEFAULT_SIZE; import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.util.Collections; import java.util.List; import javax.swing.GroupLayout; import javax.swing.JButton; import javax.swing.JFileChooser; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.JToolBar; import javax.swing.LayoutStyle.ComponentPlacement; import javax.swing.ListSelectionModel; import javax.swing.table.AbstractTableModel; import org.lateralgm.components.CustomFileChooser; import org.lateralgm.components.impl.CustomFileFilter; import org.lateralgm.components.impl.ResNode; import org.lateralgm.file.ProjectFile; import org.lateralgm.file.GmStreamDecoder; import org.lateralgm.file.GmStreamEncoder; import org.lateralgm.main.LGM; import org.lateralgm.messages.Messages; import org.lateralgm.resources.Constants; import org.lateralgm.resources.Constants.PConstants; import org.lateralgm.resources.sub.Constant; public class ConstantsFrame extends ResourceFrame<Constants,PConstants> { private static final long serialVersionUID = 1L; public JToolBar toolbar; public JButton importBut; public JButton exportBut; public JTable constants; public ConstantsTableModel cModel; public JButton add; public JButton insert; public JButton delete; public JButton clear; public JButton up; public JButton down; public JButton sort; private CustomFileChooser constantsFc; private class ConstantsTableModel extends AbstractTableModel { private static final long serialVersionUID = 1L; List<Constant> constants; ConstantsTableModel(List<Constant> list) { constants = ProjectFile.copyConstants(list); } public int getColumnCount() { return 2; } public int getRowCount() { return constants.size(); } public Object getValueAt(int rowIndex, int columnIndex) { Constant c = constants.get(rowIndex); return (columnIndex == 0) ? c.name : c.value; } public void setValueAt(Object aValue, int rowIndex, int columnIndex) { Constant c = constants.get(rowIndex); if (columnIndex == 0) c.name = aValue.toString(); else c.value = aValue.toString(); } public boolean isCellEditable(int row, int col) { return true; } public String getColumnName(int column) { String ind = (column == 0) ? "NAME" : "VALUE"; //$NON-NLS-1$ //$NON-NLS-2$ return Messages.getString("ConstantsFrame." + ind); //$NON-NLS-1$ } public void removeEmptyConstants() { for (int i = constants.size() - 1; i >= 0; i--) if (constants.get(i).name.equals("")) constants.remove(i); //$NON-NLS-1$ fireTableDataChanged(); } } public ConstantsFrame(Constants res) { this(res,null); } public void updateTitle() { String name = res.getName(); if (res == LGM.currentFile.defaultConstants) name = "All Configurations"; this.setTitle(Messages.getString("ConstantsFrame.TITLE") + " : " + name); } public ConstantsFrame(Constants res, ResNode node) { super(res,node); //$NON-NLS-1$ setDefaultCloseOperation(HIDE_ON_CLOSE); setTitle(Messages.getString("ConstantsFrame.TITLE")); JPanel content = new JPanel(); GroupLayout layout = new GroupLayout(content); layout.setAutoCreateGaps(true); layout.setAutoCreateContainerGaps(true); //this.setLayout(layout); content.setLayout(layout); this.setLayout(new BorderLayout()); toolbar = new JToolBar(); toolbar.setFloatable(false); toolbar.add(save); toolbar.addSeparator(); exportBut = new JButton(LGM.getIconForKey("ConstantsFrame.EXPORT")); //$NON-NLS-1$ exportBut.setToolTipText(Messages.getString("ConstantsFrame.EXPORT")); exportBut.addActionListener(this); toolbar.add(exportBut); importBut = new JButton(LGM.getIconForKey("ConstantsFrame.IMPORT")); //$NON-NLS-1$ importBut.setToolTipText(Messages.getString("ConstantsFrame.IMPORT")); importBut.addActionListener(this); toolbar.add(importBut); //toolbar.addSeparator(); //toolbar.add(new JLabel("Configuration:")); //String strs[] = { "All Configurations","Default" }; //JComboBox<String> configCombo = new JComboBox<String>(strs); //configCombo.setMaximumSize(new Dimension(130,22)); //toolbar.add(configCombo); this.add(toolbar,BorderLayout.NORTH); this.add(content,BorderLayout.CENTER); cModel = new ConstantsTableModel(res.constants); constants = new JTable(cModel); JScrollPane scroll = new JScrollPane(constants); constants.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); constants.getTableHeader().setReorderingAllowed(false); constants.setTransferHandler(null); //this fixes java bug 4709394, where the cell editor does not commit on focus lost, //causing the value to remain in-limbo even after the "Save" button is clicked. constants.putClientProperty("terminateEditOnFocusLost",Boolean.TRUE); //$NON-NLS-1$ add = new JButton(Messages.getString("ConstantsFrame.ADD")); //$NON-NLS-1$ add.addActionListener(this); insert = new JButton(Messages.getString("ConstantsFrame.INSERT")); //$NON-NLS-1$ insert.addActionListener(this); delete = new JButton(Messages.getString("ConstantsFrame.DELETE")); //$NON-NLS-1$ delete.addActionListener(this); clear = new JButton(Messages.getString("ConstantsFrame.CLEAR")); //$NON-NLS-1$ clear.addActionListener(this); up = new JButton(Messages.getString("ConstantsFrame.UP")); //$NON-NLS-1$ up.addActionListener(this); down = new JButton(Messages.getString("ConstantsFrame.DOWN")); //$NON-NLS-1$ down.addActionListener(this); sort = new JButton(Messages.getString("ConstantsFrame.SORT")); //$NON-NLS-1$ sort.addActionListener(this); constantsFc = new CustomFileChooser("/org/lateralgm","LAST_LGC_DIR"); //$NON-NLS-1$ //$NON-NLS-2$ constantsFc.setFileFilter(new CustomFileFilter( Messages.getString("ConstantsFrame.LGC_FILES"),".lgc")); //$NON-NLS-1$ //$NON-NLS-2$ layout.setHorizontalGroup(layout.createParallelGroup() /**/.addComponent(scroll) /**/.addGroup(layout.createSequentialGroup() /* */.addGroup(layout.createParallelGroup() /* */.addComponent(add,DEFAULT_SIZE,DEFAULT_SIZE,MAX_VALUE) /* */.addComponent(insert,DEFAULT_SIZE,DEFAULT_SIZE,MAX_VALUE)) /* */.addGroup(layout.createParallelGroup() /* */.addComponent(delete,DEFAULT_SIZE,DEFAULT_SIZE,MAX_VALUE) /* */.addComponent(clear,DEFAULT_SIZE,DEFAULT_SIZE,MAX_VALUE)) /* */.addPreferredGap(ComponentPlacement.UNRELATED) /* */.addGroup(layout.createParallelGroup() /* */.addComponent(up,DEFAULT_SIZE,DEFAULT_SIZE,MAX_VALUE) /* */.addComponent(down,DEFAULT_SIZE,DEFAULT_SIZE,MAX_VALUE)) /* */.addComponent(sort,DEFAULT_SIZE,DEFAULT_SIZE,MAX_VALUE))); layout.setVerticalGroup(layout.createSequentialGroup() /**/.addComponent(scroll,DEFAULT_SIZE,300,MAX_VALUE) /**/.addGroup(layout.createParallelGroup() /* */.addComponent(add) /* */.addComponent(delete) /* */.addComponent(up) /* */.addComponent(sort)) /**/.addGroup(layout.createParallelGroup() /* */.addComponent(insert) /* */.addComponent(clear) /* */.addComponent(down))); pack(); } public void actionPerformed(ActionEvent e) { super.actionPerformed(e); if (e.getSource() == importBut) { importConstants(); return; } if (e.getSource() == exportBut) { exportConstants(); return; } if (e.getSource() == add) { if (constants.getCellEditor() != null) constants.getCellEditor().stopCellEditing(); cModel.constants.add(new Constant()); int row = cModel.constants.size() - 1; cModel.fireTableRowsInserted(row,row); constants.getSelectionModel().setSelectionInterval(row,row); return; } if (e.getSource() == insert) { if (constants.getSelectedRow() == -1) return; if (constants.getCellEditor() != null) constants.getCellEditor().stopCellEditing(); cModel.constants.add(constants.getSelectedRow(),new Constant()); cModel.fireTableRowsInserted(constants.getSelectedRow(),constants.getSelectedRow()); constants.getSelectionModel().setSelectionInterval(0,constants.getSelectedRow() - 1); return; } if (e.getSource() == delete) { if (constants.getSelectedRow() == -1) return; int row = constants.getSelectedRow(); cModel.constants.remove(row); cModel.fireTableRowsDeleted(row,row); if (cModel.constants.size() > 0) constants.getSelectionModel().setSelectionInterval(0, Math.min(row,cModel.constants.size() - 1)); return; } if (e.getSource() == clear) { if (cModel.constants.size() == 0) return; int last = cModel.constants.size() - 1; cModel.constants.clear(); cModel.fireTableRowsDeleted(0,last); return; } if (e.getSource() == up) { int row = constants.getSelectedRow(); if (row <= 0) return; if (constants.getCellEditor() != null) constants.getCellEditor().stopCellEditing(); Constant c = cModel.constants.get(row - 1); cModel.constants.set(row - 1,cModel.constants.get(row)); cModel.constants.set(row,c); cModel.fireTableDataChanged(); constants.getSelectionModel().setSelectionInterval(0,row - 1); return; } if (e.getSource() == down) { int row = constants.getSelectedRow(); if (row == -1 || row >= cModel.constants.size() - 1) return; if (constants.getCellEditor() != null) constants.getCellEditor().stopCellEditing(); Constant c = cModel.constants.get(row + 1); cModel.constants.set(row + 1,cModel.constants.get(row)); cModel.constants.set(row,c); cModel.fireTableDataChanged(); constants.getSelectionModel().setSelectionInterval(0,row + 1); return; } if (e.getSource() == sort) { if (constants.getCellEditor() != null) constants.getCellEditor().stopCellEditing(); Collections.sort(cModel.constants); cModel.fireTableDataChanged(); if (cModel.constants.size() > 0) constants.getSelectionModel().setSelectionInterval(0,0); return; } } private void importConstants() { if (constantsFc.showOpenDialog(LGM.frame) == JFileChooser.APPROVE_OPTION) { cModel.removeEmptyConstants(); GmStreamDecoder in = null; try { File f = constantsFc.getSelectedFile(); if (f == null || !f.exists()) throw new Exception(); in = new GmStreamDecoder(f); if (in.read3() != ('L' | ('G' << 8) | ('C' << 16))) throw new Exception(); int count = in.read2(); for (int i = 0; i < count; i++) { Constant c = new Constant(); c.name = in.readStr1(); c.value = in.readStr1(); if (!cModel.constants.contains(c)) cModel.constants.add(c); } cModel.fireTableDataChanged(); if (cModel.constants.size() > 0) constants.getSelectionModel().setSelectionInterval(0,0); } catch (Exception ex) { JOptionPane.showMessageDialog(LGM.frame, Messages.getString("ConstantsFrame.ERROR_IMPORTING_CONSTANTS"), //$NON-NLS-1$ Messages.getString("ConstantsFrame.TITLE_ERROR"),JOptionPane.ERROR_MESSAGE); //$NON-NLS-1$ } finally { if (in != null) try { in.close(); } catch (IOException e) { e.printStackTrace(); } } } } private void exportConstants() { while (constantsFc.showSaveDialog(LGM.frame) == JFileChooser.APPROVE_OPTION) { File f = constantsFc.getSelectedFile(); if (f == null) return; if (!f.getPath().endsWith(".lgc")) f = new File(f.getPath() + ".lgc"); //$NON-NLS-1$ //$NON-NLS-2$ int result = 0; if (f.exists()) { result = JOptionPane.showConfirmDialog(LGM.frame, Messages.getString("ConstantsFrame.REPLACE_FILE"), //$NON-NLS-1$ Messages.getString("ConstantsFrame.TITLE_REPLACE_FILE"), //$NON-NLS-1$ JOptionPane.YES_NO_CANCEL_OPTION); } if (result == 2) return; if (result == 1) continue; cModel.removeEmptyConstants(); GmStreamEncoder out = null; try { out = new GmStreamEncoder(f); out.write('L'); out.write('G'); out.write('C'); out.write2(cModel.constants.size()); for (Constant c : cModel.constants) { out.writeStr1(c.name); out.writeStr1(c.value); } } catch (FileNotFoundException e1) { e1.printStackTrace(); } catch (IOException ex) { ex.printStackTrace(); } finally { if (out != null) try { out.close(); } catch (IOException ex) { ex.printStackTrace(); } } return; } } public void commitChanges() { //Constants cModel.removeEmptyConstants(); res.constants = ProjectFile.copyConstants(cModel.constants); } public void setComponents(Constants c) { //Constants cModel = new ConstantsTableModel(c.constants); constants.setModel(cModel); constants.updateUI(); } @Override public boolean resourceChanged() { commitChanges(); return !res.properties.equals(resOriginal.properties) || !res.constants.equals(resOriginal.constants); } @Override public void revertResource() { resOriginal.copy(res); setComponents(res); } @Override public void updateResource(boolean commit) { super.updateResource(commit); } }