View Javadoc

1   /*
2    * SymmetricDS is an open source database synchronization solution.
3    *   
4    * Copyright (C) Chris Henson <chenson42@users.sourceforge.net>
5    *
6    * This library is free software; you can redistribute it and/or
7    * modify it under the terms of the GNU Lesser General Public
8    * License as published by the Free Software Foundation; either
9    * version 3 of the License, or (at your option) any later version.
10   *
11   * This library is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14   * Lesser General Public License for more details.
15   *
16   * You should have received a copy of the GNU Lesser General Public
17   * License along with this library; if not, see
18   * <http://www.gnu.org/licenses/>.
19   */
20  package org.jumpmind.symmetric.admin;
21  
22  import java.awt.BorderLayout;
23  import java.awt.Component;
24  import java.awt.event.WindowAdapter;
25  import java.awt.event.WindowEvent;
26  
27  import javax.swing.JFrame;
28  import javax.swing.JPanel;
29  import javax.swing.JScrollPane;
30  import javax.swing.JTable;
31  import javax.swing.JTextArea;
32  import javax.swing.ListSelectionModel;
33  import javax.swing.UIManager;
34  import javax.swing.border.TitledBorder;
35  import javax.swing.event.ListSelectionEvent;
36  import javax.swing.event.ListSelectionListener;
37  import javax.swing.event.TableModelEvent;
38  import javax.swing.event.TableModelListener;
39  import javax.swing.table.DefaultTableCellRenderer;
40  import javax.swing.table.TableCellEditor;
41  import javax.swing.table.TableColumn;
42  
43  import org.jumpmind.symmetric.admin.table.ChannelTableModel;
44  import org.jumpmind.symmetric.admin.table.ModelObjectTableModel;
45  import org.jumpmind.symmetric.admin.table.ValidationException;
46  import org.jumpmind.symmetric.model.Channel;
47  
48  public class ChannelEditScreen extends AbstractScreen {
49  
50      private static final long serialVersionUID = -843273502686831584L;
51  
52      protected JTable table;
53  
54      protected JScrollPane scroller;
55  
56      protected ModelObjectTableModel<Channel> tableModel;
57  
58      int selectedRow = 0;
59  
60      public ChannelEditScreen() {
61          
62          tableModel = new ChannelTableModel();
63          tableModel.addTableModelListener(new ChannelEditScreen.InteractiveTableModelListener());
64          table = new JTable();
65          table.setModel(tableModel);
66          table.setSurrendersFocusOnKeystroke(true);
67          if (!tableModel.hasEmptyRow()) {
68              tableModel.addEmptyRow();
69          }
70  
71          scroller = new javax.swing.JScrollPane(table);
72          table.setPreferredScrollableViewportSize(new java.awt.Dimension(500, 300));
73          TableColumn hidden = table.getColumnModel().getColumn(tableModel.getColumnCount() - 1);
74          hidden.setMinWidth(2);
75          hidden.setPreferredWidth(2);
76          hidden.setMaxWidth(2);
77          hidden.setCellRenderer(new InteractiveRenderer(tableModel.getColumnCount() - 1));
78  
79          table.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
80  
81          table.getSelectionModel().addListSelectionListener(tableModel);
82  
83          table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
84              public void valueChanged(ListSelectionEvent e) {
85                  if (!e.getValueIsAdjusting()) {
86                      int oldRow = selectedRow;
87                      selectedRow = table.getSelectedRow();
88                      System.out.println("selection changed to " + selectedRow);
89                      try {
90                          tableModel.save();
91                      } catch (ValidationException e1) {
92                          table.getSelectionModel().setSelectionInterval(oldRow, oldRow);
93                      }
94                      if (!ChannelEditScreen.this.tableModel.hasEmptyRow()) {
95                          ChannelEditScreen.this.tableModel.addEmptyRow();
96                      }
97                  }
98              }
99          });
100 
101         int columnCount = tableModel.getColumnCount();
102         for (int columnIndex = 0; columnIndex < columnCount; columnIndex++) {
103             TableColumn column = table.getColumnModel().getColumn(columnIndex);
104             TableCellEditor editor = tableModel.getCellEditorForColumn(columnIndex);
105             if (editor != null) {
106                 column.setCellEditor(editor);
107             }
108         }
109 
110         setLayout(new BorderLayout(5,5));
111         
112         JPanel instructionsPanel = new JPanel();
113         // TODO from resource bundle
114         instructionsPanel.setBorder(new TitledBorder("Channels"));
115         instructionsPanel.setLayout(new BorderLayout());
116         JTextArea area = new JTextArea();
117         area.setEditable(false);
118         area.setOpaque(false);
119         // TODO resource bundle
120         area.setText("Channels are ...");
121         instructionsPanel.add(area, BorderLayout.CENTER);
122         
123         add(instructionsPanel, BorderLayout.NORTH);
124         add(scroller, BorderLayout.CENTER);
125     }
126     
127     @Override
128     public ScreenName getScreenName() {
129         return ScreenName.CHANNELS;
130     }
131     
132     @Override
133     public void setup(SymmetricDatabase c) {
134         tableModel.setup(c);
135     }
136 
137     public void highlightLastRow(int row) {
138         int lastrow = tableModel.getRowCount();
139         if (row == lastrow - 1) {
140             table.setRowSelectionInterval(lastrow - 1, lastrow - 1);
141         } else {
142             table.setRowSelectionInterval(row + 1, row + 1);
143         }
144 
145         table.setColumnSelectionInterval(0, 0);
146     }
147 
148     @SuppressWarnings("serial")
149     class InteractiveRenderer extends DefaultTableCellRenderer {
150         protected int interactiveColumn;
151 
152         public InteractiveRenderer(int interactiveColumn) {
153             this.interactiveColumn = interactiveColumn;
154         }
155 
156         public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
157                 boolean hasFocus, int row, int column) {
158             Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
159             if (column == interactiveColumn && hasFocus) {
160                 if ((ChannelEditScreen.this.tableModel.getRowCount() - 1) == row && !ChannelEditScreen.this.tableModel.hasEmptyRow()) {
161                     ChannelEditScreen.this.tableModel.addEmptyRow();
162                 }
163 
164                 highlightLastRow(row);
165             }
166 
167             return c;
168         }
169     }
170 
171     public class InteractiveTableModelListener implements TableModelListener {
172         public void tableChanged(TableModelEvent evt) {
173             if (evt.getType() == TableModelEvent.UPDATE) {
174                 int column = evt.getColumn();
175                 int row = evt.getFirstRow();
176                 System.out.println("row: " + row + " column: " + column);
177                 table.setColumnSelectionInterval(column + 1, column + 1);
178                 table.setRowSelectionInterval(row, row);
179             }
180         }
181     }
182 
183     public static void main(String[] args) {
184         try {
185             UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
186             JFrame frame = new JFrame("Interactive Form");
187             frame.addWindowListener(new WindowAdapter() {
188                 public void windowClosing(WindowEvent evt) {
189                     System.exit(0);
190                 }
191             });
192             frame.getContentPane().add(new ChannelEditScreen());
193             frame.pack();
194             frame.setVisible(true);
195         } catch (Exception e) {
196             e.printStackTrace();
197         }
198     }
199 }