Java tutorial
/* * Copyright 2015 heming.keh@gmail.com * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package io.heming.accountbook.ui; import io.heming.accountbook.constants.Constants; import io.heming.accountbook.entity.Category; import io.heming.accountbook.entity.Record; import io.heming.accountbook.facade.CategoryFacade; import io.heming.accountbook.facade.FacadeUtil; import io.heming.accountbook.facade.Pages; import io.heming.accountbook.facade.RecordFacade; import io.heming.accountbook.util.DateUtil; import io.heming.accountbook.util.ZIPUtil; import org.apache.commons.io.FileUtils; import javax.swing.*; import javax.swing.border.EtchedBorder; import javax.swing.table.TableColumnModel; import java.awt.*; import java.awt.event.*; import java.io.File; import java.io.IOException; import java.sql.Date; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; import java.util.List; /** * Created by Keh on 2015/5/18. */ public class MainFrame extends JFrame { private List<Category> categories; private CategoryFacade categoryFacade; private RecordFacade recordFacade; private Pages.Builder builder; private Pages pages; private JTable table; private TableModel model; // Menu bar private JMenuBar menuBar; // File menu private JMenu fileMenu; private JMenuItem importMenuItem; private JMenuItem exportMenuItem; private JMenuItem quitMenuItem; // Edit menu private JMenu editMenu; private JMenuItem addRecordMenuItem; // private JMenuItem deleteRecordMenuItem; private JMenuItem categoryMenuItem; // View menu private JMenu viewMenu; private JMenuItem searchMenuItem; private JMenuItem firstPageMenuItem; private JMenuItem prevPageMenuItem; private JMenuItem nextPageMenuItem; private JMenuItem lastPageMenuItem; private JMenuItem keywordMenuItem; /** * Help menu. */ private JMenu helpMenu; /** * Help menu item. */ private JMenuItem helpMenuItem; /** * About menu item. */ private JMenuItem aboutMenuItem; /** * Tool bar. */ private JToolBar toolbar; /** * A button for add record. */ private JButton addButton; /** * To select date range of current year. */ private JToggleButton yearToggleButton; /** * To select date range of current month. */ private JToggleButton monthToggleButton; /** * To select date range of current day. */ private JToggleButton dayToggleButton; /** * To select all date range. */ private JToggleButton customToggleButton; private static final String SHOW_DATE_CHOOSER = "SHOW DATE CHOOSER"; private static final String HIDE_DATE_CHOOSER = "HIDE DATE CHOOSER"; private JSpinner startDateSpinner; private JSpinner endDateSpinner; private JPanel cards; private boolean date_chooser_visible; /** * Keyword text field. */ private JTextField keywordTextField; /** * Search button. */ private JButton searchButton; /** * Status bar. */ private Box statusBar; /** * A label to display the current status messages. */ private JLabel statusLabel; /** * Go to the next page view button. */ private JButton nextPageButton; /** * Go to the previous page view button. */ private JButton prevPageButton; /** * Go to the first page view button. */ private JButton firstPageButton; /** * Go to the last page view button. */ private JButton lastPageButton; private JLabel infoLabel; private JLabel pageLabel; /** * ???????disable? */ private boolean disable; public MainFrame() throws Exception { categoryFacade = new CategoryFacade(); recordFacade = new RecordFacade(); builder = new Pages.Builder(); builder.order("id", false); pages = builder.make(); date_chooser_visible = false; disable = false; // Create widgets model = new TableModel(); table = new JTable(model) { /** * tip. * * @param evt * @return */ @Override public String getToolTipText(MouseEvent evt) { String tip = null; java.awt.Point point = evt.getPoint(); int row = rowAtPoint(point); int col = columnAtPoint(point); Rectangle bounds = getCellRect(row, col, false); Component comp = prepareRenderer(getCellRenderer(row, col), row, col); try { if (comp.getPreferredSize().width > bounds.width) { tip = getValueAt(row, col).toString(); } } catch (RuntimeException e) { //catch null pointer exception if mouse is over an empty line } return tip; } }; if (pages.hasNext()) { model.setRecords(pages.next()); } // ? table.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS); TableColumnModel columnModel = table.getColumnModel(); columnModel.getColumn(0).setPreferredWidth(80); columnModel.getColumn(1).setPreferredWidth(160); columnModel.getColumn(2).setPreferredWidth(80); columnModel.getColumn(3).setPreferredWidth(100); columnModel.getColumn(4).setPreferredWidth(100); columnModel.getColumn(5).setPreferredWidth(360); // Layout JScrollPane pane = new JScrollPane(table); add(pane, BorderLayout.CENTER); table.getTableHeader().setReorderingAllowed(false); table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); // table header table.getTableHeader().addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { int col = table.columnAtPoint(e.getPoint()); String name = table.getColumnName(col); // TODO } }); // ? addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { quit(); } }); categories = categoryFacade.listBySale(); initMenuBar(); initToolBar(); initStatusBar(); initTablePopupMenu(); searchRecords(); setIconImage(new ImageIcon(getClass().getResource("64.png")).getImage()); setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); setTitle(""); setSize(860, 620); } private void setStatusText(String text) { statusLabel.setText(text); } private void importRecords() { final JFileChooser chooser = new JFileChooser(); chooser.setFileSelectionMode(JFileChooser.FILES_ONLY); chooser.addChoosableFileFilter(new AbbFileFilter()); chooser.setAcceptAllFileFilterUsed(false); int value = chooser.showOpenDialog(this); if (value == JFileChooser.APPROVE_OPTION) { // ? disableAllControls(); new Thread() { @Override public void run() { try { statusLabel.setIcon(new ImageIcon(getClass().getResource("loader.gif"))); setStatusText("?..."); FacadeUtil.shutdown(); File file = chooser.getSelectedFile(); setStatusText("??..."); FileUtils.cleanDirectory(new File(Constants.DATA_DIR)); setStatusText("??..."); ZIPUtil.decompress(file, new File(Constants.HOME_DIR)); setStatusText("?..."); FacadeUtil.restart(); // ?? setStatusText("????..."); categories = categoryFacade.listBySale(); // ???? setStatusText("?..."); searchRecords(); enableAllControls(); setStatusText(""); statusLabel.setIcon(new ImageIcon(getClass().getResource("stopped-loader.png"))); JOptionPane.showMessageDialog(MainFrame.this, "???", "?", JOptionPane.INFORMATION_MESSAGE); } catch (Exception e) { JOptionPane.showMessageDialog(MainFrame.this, e.getMessage(), "", JOptionPane.ERROR_MESSAGE); } } }.start(); } } private void exportRecords() { final JFileChooser chooser = new JFileChooser(); chooser.setFileSelectionMode(JFileChooser.FILES_ONLY); chooser.addChoosableFileFilter(new AbbFileFilter()); chooser.setAcceptAllFileFilterUsed(false); int value = chooser.showSaveDialog(this); if (value == JFileChooser.APPROVE_OPTION) { final File file = chooser.getSelectedFile(); disableAllControls(); new Thread() { @Override public void run() { try { statusLabel.setIcon(new ImageIcon(getClass().getResource("loader.gif"))); setStatusText("?..."); FacadeUtil.shutdown(); // .abb? setStatusText("?..."); List<String> exclusion = Arrays.asList(); if (!file.getName().endsWith(".abb")) { ZIPUtil.compress(new File(Constants.DATA_DIR), new File(file.getAbsolutePath() + ".abb"), exclusion); } else { ZIPUtil.compress(new File(Constants.DATA_DIR), file, exclusion); } setStatusText("??..."); FacadeUtil.restart(); enableAllControls(); setStatusText(""); statusLabel.setIcon(new ImageIcon(getClass().getResource("stopped-loader.png"))); JOptionPane.showMessageDialog(MainFrame.this, String.format("?"), "?", JOptionPane.INFORMATION_MESSAGE); } catch (IOException e) { JOptionPane.showMessageDialog(MainFrame.this, String.format(""), "", JOptionPane.ERROR_MESSAGE); } } }.start(); } } private void quit() { if (disable) return; disableAllControls(); statusLabel.setIcon(new ImageIcon(getClass().getResource("loader.gif"))); statusLabel.setText("..."); new Thread() { @Override public void run() { FacadeUtil.shutdown(); System.exit(0); } }.start(); } public java.util.List<Category> getCategories() { return this.categories; } public void addRecord(Record record) throws Exception { recordFacade.add(record); searchRecords(); } public void addCategory(Category category) throws Exception { categoryFacade.add(category); categories.add(category); } public void deleteCategory(Category category) throws Exception { categoryFacade.delete(category); categories.remove(category); } public void updateRecord(Record record) throws Exception { recordFacade.update(record); searchRecords(); } private void showAddRecordDialog() { if (categories.isEmpty()) { JOptionPane.showMessageDialog(this, "???????", "", JOptionPane.ERROR_MESSAGE); return; } System.out.println("add record"); try { Record record = new Record(); record.setCategory(categories.get(0)); record.setPrice(48.0); record.setDate(new Date(Calendar.getInstance().getTimeInMillis())); RecordDialog dialog = new RecordDialog(record, this, false); dialog.setSize(400, 250); dialog.setLocationRelativeTo(this); dialog.setIconImage(new ImageIcon(getClass().getResource("edit-add-3.png")).getImage()); dialog.setVisible(true); } catch (Exception e) { JOptionPane.showMessageDialog(this, e.getMessage(), "", JOptionPane.ERROR_MESSAGE); e.printStackTrace(); } } private void showUpdateRecordDialog(Record record) { try { RecordDialog dialog = new RecordDialog(record, this, true); dialog.setSize(400, 250); dialog.setLocationRelativeTo(this); dialog.setIconImage(new ImageIcon(getClass().getResource("edit-4.png")).getImage()); dialog.setVisible(true); } catch (Exception e) { JOptionPane.showMessageDialog(this, e.getMessage(), "", JOptionPane.ERROR_MESSAGE); e.printStackTrace(); } } private void deleteRecord() { int selectedRow = table.getSelectedRow(); if (selectedRow < 0) { JOptionPane.showMessageDialog(MainFrame.this, "", "", JOptionPane.ERROR_MESSAGE); return; } Record record = model.getRecord(table.convertRowIndexToModel(selectedRow)); System.out.println(record); if (JOptionPane.showConfirmDialog(MainFrame.this, String.format("??%d?", record.getId()), "", JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.OK_OPTION) { try { recordFacade.delete(record); searchRecords(); } catch (Exception e1) { e1.printStackTrace(); JOptionPane.showMessageDialog(MainFrame.this, e1.getMessage(), "", JOptionPane.ERROR_MESSAGE); } } } public void refreshCategories() throws Exception { categories = categoryFacade.list(); } private void showCategoryDialog() { CategoryDialog dialog = new CategoryDialog(this); dialog.setSize(400, 250); dialog.setLocationRelativeTo(this); dialog.setVisible(true); } private void searchRecords() { String keyword = keywordTextField.getText().trim(); builder.keyword(keyword); if (customToggleButton.isSelected()) { builder.start(new Date(((java.util.Date) startDateSpinner.getValue()).getTime())) .end(new Date(((java.util.Date) endDateSpinner.getValue()).getTime())); } else if (yearToggleButton.isSelected()) { builder.year(); } else if (monthToggleButton.isSelected()) { builder.month(); } else { builder.day(); } try { pages = builder.make(); if (pages.hasNext()) { List<Record> records = pages.next(); model.setRecords(records); } else { // ? model.setRecords(new ArrayList<>()); } infoLabel.setText(pages.getInfo()); updateNavStatus(); } catch (Exception e) { JOptionPane.showMessageDialog(this, e.getMessage(), "", JOptionPane.ERROR_MESSAGE); e.printStackTrace(); } } private void prevPage() { if (pages != null && pages.hasPrev()) { try { List<Record> records = pages.prev(); model.setRecords(records); updateNavStatus(); } catch (Exception e) { e.printStackTrace(); JOptionPane.showMessageDialog(this, e.getMessage(), "", JOptionPane.ERROR_MESSAGE); } } } private void nextPage() { if (pages != null && pages.hasNext()) { try { List<Record> records = pages.next(); model.setRecords(records); updateNavStatus(); } catch (Exception e) { e.printStackTrace(); JOptionPane.showMessageDialog(this, e.getMessage(), "", JOptionPane.ERROR_MESSAGE); } } } private void lastPage() { if (pages != null && pages.hasNext()) { try { List<Record> records = pages.last(); model.setRecords(records); updateNavStatus(); } catch (Exception e) { e.printStackTrace(); JOptionPane.showMessageDialog(this, e.getMessage(), "", JOptionPane.ERROR_MESSAGE); } } } private void firstPage() { if (pages != null && pages.hasPrev()) { try { List<Record> records = pages.first(); model.setRecords(records); updateNavStatus(); } catch (Exception e) { e.printStackTrace(); JOptionPane.showMessageDialog(this, e.getMessage(), "", JOptionPane.ERROR_MESSAGE); } } } private void chooseDateRange() { CardLayout layout = (CardLayout) cards.getLayout(); if (date_chooser_visible) { layout.show(cards, HIDE_DATE_CHOOSER); date_chooser_visible = false; customToggleButton.setSelected(true); searchRecords(); } else { layout.show(cards, SHOW_DATE_CHOOSER); date_chooser_visible = true; } } private void about() { JOptionPane.showMessageDialog(this, "\nheming_keh\n" + "heming.keh@gmail.com\n" + "https://github.com/heming-keh/AccountBook", "", JOptionPane.PLAIN_MESSAGE, new ImageIcon(getClass().getResource("64.png"))); } private void help() { try { new ProcessBuilder("cmd", "/C", ".chm").start(); } catch (IOException e) { e.printStackTrace(); } } private void updateNavStatus() { if (pages == null) { lastPageButton.setEnabled(false); lastPageMenuItem.setEnabled(false); firstPageButton.setEnabled(false); firstPageMenuItem.setEnabled(false); nextPageButton.setEnabled(false); nextPageMenuItem.setEnabled(false); prevPageButton.setEnabled(false); prevPageMenuItem.setEnabled(false); } else { if (!pages.hasNext()) { lastPageButton.setEnabled(false); lastPageMenuItem.setEnabled(false); nextPageButton.setEnabled(false); nextPageMenuItem.setEnabled(false); } else { lastPageButton.setEnabled(true); lastPageMenuItem.setEnabled(true); nextPageButton.setEnabled(true); nextPageMenuItem.setEnabled(true); } if (!pages.hasPrev()) { firstPageButton.setEnabled(false); firstPageMenuItem.setEnabled(false); prevPageButton.setEnabled(false); prevPageMenuItem.setEnabled(false); } else { firstPageButton.setEnabled(true); firstPageMenuItem.setEnabled(true); prevPageButton.setEnabled(true); prevPageMenuItem.setEnabled(true); } } pageLabel.setText(pages.getPageString()); } private void disableAllControls() { importMenuItem.setEnabled(false); exportMenuItem.setEnabled(false); quitMenuItem.setEnabled(false); addRecordMenuItem.setEnabled(false); addButton.setEnabled(false); // deleteRecordMenuItem.setEnabled(false); categoryMenuItem.setEnabled(false); searchMenuItem.setEnabled(false); searchButton.setEnabled(false); keywordTextField.setEnabled(false); keywordMenuItem.setEnabled(false); prevPageMenuItem.setEnabled(false); prevPageButton.setEnabled(false); nextPageMenuItem.setEnabled(false); nextPageButton.setEnabled(false); firstPageMenuItem.setEnabled(false); firstPageButton.setEnabled(false); lastPageMenuItem.setEnabled(false); lastPageButton.setEnabled(false); yearToggleButton.setEnabled(false); monthToggleButton.setEnabled(false); dayToggleButton.setEnabled(false); customToggleButton.setEnabled(false); disable = true; } private void enableAllControls() { importMenuItem.setEnabled(true); exportMenuItem.setEnabled(true); quitMenuItem.setEnabled(true); addRecordMenuItem.setEnabled(true); addButton.setEnabled(true); // deleteRecordMenuItem.setEnabled(true); categoryMenuItem.setEnabled(true); searchMenuItem.setEnabled(true); searchButton.setEnabled(true); keywordTextField.setEnabled(true); keywordMenuItem.setEnabled(true); // prevPageMenuItem.setEnabled(true); // prevPageButton.setEnabled(true); // nextPageMenuItem.setEnabled(true); // nextPageButton.setEnabled(true); // firstPageMenuItem.setEnabled(true); // firstPageButton.setEnabled(true); // lastPageMenuItem.setEnabled(true); // lastPageButton.setEnabled(true); updateNavStatus(); yearToggleButton.setEnabled(true); monthToggleButton.setEnabled(true); dayToggleButton.setEnabled(true); customToggleButton.setEnabled(true); disable = false; } private void initToolBar() { toolbar = new JToolBar("ToolBar", JToolBar.HORIZONTAL); // Add Button addButton = new JButton(); addButton.setActionCommand(""); addButton.setToolTipText(""); addButton.setIcon(new ImageIcon(getClass().getResource("edit-add-3.png"))); // Search date range radio buttons ButtonGroup group = new ButtonGroup(); yearToggleButton = new JToggleButton(); yearToggleButton.setToolTipText(""); yearToggleButton.setIcon(new ImageIcon(getClass().getResource("year-s.png"))); group.add(yearToggleButton); monthToggleButton = new JToggleButton(); monthToggleButton.setToolTipText(""); monthToggleButton.setIcon(new ImageIcon(getClass().getResource("month-s.png"))); group.add(monthToggleButton); dayToggleButton = new JToggleButton(); dayToggleButton.setToolTipText(""); dayToggleButton.setIcon(new ImageIcon(getClass().getResource("day-s.png"))); group.add(dayToggleButton); customToggleButton = new JToggleButton(); customToggleButton.setToolTipText(""); customToggleButton.setIcon(new ImageIcon(getClass().getResource("all-s.png"))); group.add(customToggleButton); // ??Checkbox monthToggleButton.setSelected(true); Calendar earliestCalendar = Calendar.getInstance(); earliestCalendar.add(Calendar.YEAR, -100); java.util.Date earliestDate = earliestCalendar.getTime(); Calendar latestCalendar = Calendar.getInstance(); latestCalendar.add(Calendar.YEAR, 100); java.util.Date latestDate = latestCalendar.getTime(); // 3? Calendar calendar = Calendar.getInstance(); calendar.add(Calendar.MONTH, -1); calendar.add(Calendar.DAY_OF_MONTH, 1); java.util.Date initDate = calendar.getTime(); SpinnerDateModel startDateModel = new SpinnerDateModel(DateUtil.getStartOfWeek(), earliestDate, latestDate, Calendar.MONTH); startDateSpinner = new JSpinner(startDateModel); JSpinner.DateEditor startDateEditor = new JSpinner.DateEditor(startDateSpinner, "yyyy-MM-dd"); startDateSpinner.setEditor(startDateEditor); calendar.add(Calendar.MONTH, 1); calendar.add(Calendar.DAY_OF_MONTH, -1); initDate = calendar.getTime(); SpinnerDateModel endDateModel = new SpinnerDateModel(initDate, earliestDate, latestDate, Calendar.MONTH); endDateSpinner = new JSpinner(endDateModel); JSpinner.DateEditor endDateEditor = new JSpinner.DateEditor(endDateSpinner, "yyyy-MM-dd"); endDateSpinner.setEditor(endDateEditor); // Keyword text field keywordTextField = new JTextField(); keywordTextField.setPreferredSize(new Dimension(250, 20)); keywordTextField.setMaximumSize(keywordTextField.getPreferredSize()); // Search Button searchButton = new JButton(); searchButton.setActionCommand("?"); searchButton.setToolTipText("?"); searchButton.setIcon(new ImageIcon(getClass().getResource("edit-find-5.png"))); // Layout cards = new JPanel(); cards.setLayout(new CardLayout()); Box box = Box.createHorizontalBox(); box.add(Box.createHorizontalGlue()); startDateSpinner.setPreferredSize(new Dimension(90, 20)); startDateSpinner.setMaximumSize(startDateSpinner.getPreferredSize()); box.add(startDateSpinner); box.add(Box.createHorizontalStrut(6)); endDateSpinner.setPreferredSize(new Dimension(90, 20)); endDateSpinner.setMaximumSize(endDateSpinner.getPreferredSize()); box.add(endDateSpinner); cards.add(new JPanel(), HIDE_DATE_CHOOSER); cards.add(box, SHOW_DATE_CHOOSER); Box dateRangeBox = Box.createHorizontalBox(); dateRangeBox.add(Box.createHorizontalGlue()); dateRangeBox.add(cards); toolbar.add(addButton); toolbar.add(dateRangeBox); toolbar.add(customToggleButton); toolbar.add(yearToggleButton); toolbar.add(monthToggleButton); toolbar.add(dayToggleButton); toolbar.add(keywordTextField); toolbar.add(searchButton); add(toolbar, BorderLayout.NORTH); // Event listener addButton.addActionListener(e -> showAddRecordDialog()); ActionListener listener = e -> searchRecords(); yearToggleButton.addActionListener(listener); monthToggleButton.addActionListener(listener); dayToggleButton.addActionListener(listener); customToggleButton.addActionListener(listener); keywordTextField.addActionListener(listener); searchButton.addActionListener(listener); customToggleButton.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { if (SwingUtilities.isRightMouseButton(e)) { chooseDateRange(); } } }); } private void initMenuBar() { JMenuBar menuBar = new JMenuBar(); // File menu fileMenu = new JMenu("(F)"); fileMenu.setMnemonic('F'); exportMenuItem = new JMenuItem("(B)..."); exportMenuItem.setIcon(new ImageIcon(getClass().getResource("database-save.png"))); exportMenuItem.setMnemonic('B'); exportMenuItem.addActionListener(e -> exportRecords()); fileMenu.add(exportMenuItem); importMenuItem = new JMenuItem("??(R)..."); importMenuItem.setIcon(new ImageIcon(getClass().getResource("document-import-2.png"))); importMenuItem.setMnemonic('R'); importMenuItem.addActionListener(e -> importRecords()); fileMenu.add(importMenuItem); fileMenu.addSeparator(); quitMenuItem = new JMenuItem("(X)"); quitMenuItem.setIcon(new ImageIcon(getClass().getResource("application-exit-2.png"))); quitMenuItem.setMnemonic('X'); quitMenuItem.addActionListener(e -> quit()); fileMenu.add(quitMenuItem); // View menu viewMenu = new JMenu("(V)"); viewMenu.setMnemonic('V'); searchMenuItem = new JMenuItem("?(S)"); searchMenuItem.setIcon(new ImageIcon(getClass().getResource("edit-find-5.png"))); searchMenuItem.setMnemonic('S'); searchMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F3, 0)); searchMenuItem.addActionListener(e -> searchRecords()); viewMenu.add(searchMenuItem); keywordMenuItem = new JMenuItem("(K)"); keywordMenuItem.setIcon(new ImageIcon(getClass().getResource("text-field.png"))); keywordMenuItem.setMnemonic('K'); keywordMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F, Event.CTRL_MASK)); keywordMenuItem.addActionListener(e -> { keywordTextField.requestFocus(); keywordTextField.selectAll(); }); viewMenu.add(keywordMenuItem); viewMenu.addSeparator(); prevPageMenuItem = new JMenuItem("?(P)"); prevPageMenuItem.setIcon(new ImageIcon(getClass().getResource("go-previous-2.png"))); prevPageMenuItem.setMnemonic('P'); prevPageMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, Event.CTRL_MASK)); prevPageMenuItem.addActionListener(e -> prevPage()); viewMenu.add(prevPageMenuItem); nextPageMenuItem = new JMenuItem("(N)"); nextPageMenuItem.setIcon(new ImageIcon(getClass().getResource("go-next-2.png"))); nextPageMenuItem.setMnemonic('N'); nextPageMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, Event.CTRL_MASK)); nextPageMenuItem.addActionListener(e -> nextPage()); viewMenu.add(nextPageMenuItem); firstPageMenuItem = new JMenuItem("(F)"); firstPageMenuItem.setIcon(new ImageIcon(getClass().getResource("go-first.png"))); firstPageMenuItem.setMnemonic('F'); firstPageMenuItem .setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, Event.SHIFT_MASK + Event.CTRL_MASK)); firstPageMenuItem.addActionListener(e -> firstPage()); viewMenu.add(firstPageMenuItem); lastPageMenuItem = new JMenuItem("(L)"); lastPageMenuItem.setIcon(new ImageIcon(getClass().getResource("go-last.png"))); lastPageMenuItem.setMnemonic('L'); lastPageMenuItem .setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, Event.SHIFT_MASK + Event.CTRL_MASK)); lastPageMenuItem.addActionListener(e -> lastPage()); viewMenu.add(lastPageMenuItem); // Edit menu editMenu = new JMenu("(E)"); editMenu.setMnemonic('E'); addRecordMenuItem = new JMenuItem("(A)..."); addRecordMenuItem.setIcon(new ImageIcon(getClass().getResource("edit-add-3.png"))); addRecordMenuItem.setMnemonic('A'); addRecordMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, Event.CTRL_MASK)); addRecordMenuItem.addActionListener(e -> showAddRecordDialog()); editMenu.add(addRecordMenuItem); // deleteRecordMenuItem = new JMenuItem("(D)"); // deleteRecordMenuItem.setIcon(new ImageIcon(getClass().getResource("edit-delete-6.png"))); // deleteRecordMenuItem.setMnemonic('D'); // deleteRecordMenuItem.addActionListener(e -> deleteRecord()); // editMenu.add(deleteRecordMenuItem); editMenu.addSeparator(); categoryMenuItem = new JMenuItem("???(T)..."); categoryMenuItem.setIcon(new ImageIcon(getClass().getResource("view-list-icons-2.png"))); categoryMenuItem.setMnemonic('T'); categoryMenuItem.addActionListener(e -> showCategoryDialog()); editMenu.add(categoryMenuItem); // Help menu helpMenu = new JMenu("(H)"); helpMenu.setMnemonic('H'); helpMenuItem = new JMenuItem("(I)"); helpMenuItem.setIcon(new ImageIcon(getClass().getResource("help-2.png"))); helpMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F1, 0)); helpMenuItem.setMnemonic('I'); helpMenuItem.addActionListener(e -> help()); helpMenu.add(helpMenuItem); aboutMenuItem = new JMenuItem("(A)"); aboutMenuItem.setIcon(new ImageIcon(getClass().getResource("help-about-2.png"))); aboutMenuItem.setMnemonic('A'); aboutMenuItem.addActionListener(e -> about()); helpMenu.add(aboutMenuItem); // Add menu to menu bar menuBar.add(fileMenu); menuBar.add(editMenu); menuBar.add(viewMenu); menuBar.add(helpMenu); setJMenuBar(menuBar); } private void initStatusBar() { statusBar = Box.createHorizontalBox(); statusBar.setPreferredSize(new Dimension(getWidth(), 26)); statusBar.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(2, 0, 0, 0), BorderFactory.createEtchedBorder(EtchedBorder.LOWERED))); ImageIcon loading = new ImageIcon(getClass().getResource("stopped-loader.png")); statusLabel = new JLabel("", loading, JLabel.LEFT); statusLabel.setHorizontalAlignment(SwingConstants.LEFT); statusBar.add(statusLabel); statusBar.add(Box.createHorizontalGlue()); infoLabel = new JLabel(); infoLabel.setForeground(Color.GRAY); infoLabel.setPreferredSize(new Dimension(270, 20)); infoLabel.setMaximumSize(infoLabel.getPreferredSize()); statusBar.add(infoLabel); statusBar.add(Box.createHorizontalStrut(20)); pageLabel = new JLabel(); pageLabel.setForeground(Color.GRAY); pageLabel.setPreferredSize(new Dimension(80, 20)); pageLabel.setMaximumSize(pageLabel.getPreferredSize()); statusBar.add(pageLabel); Insets insets = new Insets(2, 10, 2, 10); firstPageButton = new JButton(); firstPageButton.setMargin(insets); firstPageButton.setActionCommand(""); firstPageButton.setToolTipText(""); firstPageButton.setIcon(new ImageIcon(getClass().getResource("go-first.png"))); firstPageButton.addActionListener(e -> firstPage()); prevPageButton = new JButton(); prevPageButton.setMargin(insets); prevPageButton.setActionCommand("?"); prevPageButton.setToolTipText("?"); prevPageButton.setIcon(new ImageIcon(getClass().getResource("go-previous-2.png"))); prevPageButton.addActionListener(e -> prevPage()); nextPageButton = new JButton(); nextPageButton.setMargin(insets); nextPageButton.setActionCommand(""); nextPageButton.setToolTipText(""); nextPageButton.setIcon(new ImageIcon(getClass().getResource("go-next-2.png"))); nextPageButton.addActionListener(e -> nextPage()); lastPageButton = new JButton(); lastPageButton.setMargin(insets); lastPageButton.setActionCommand(""); lastPageButton.setToolTipText(""); lastPageButton.setIcon(new ImageIcon(getClass().getResource("go-last.png"))); lastPageButton.addActionListener(e -> lastPage()); statusBar.add(firstPageButton); statusBar.add(prevPageButton); statusBar.add(nextPageButton); statusBar.add(lastPageButton); add(statusBar, BorderLayout.SOUTH); } private void initTablePopupMenu() { JPopupMenu popupMenu = new JPopupMenu(); JMenuItem deleteMenuItem = new JMenuItem("(D)", new ImageIcon(getClass().getResource("edit-delete-6.png"))); deleteMenuItem.setMnemonic('D'); popupMenu.add(deleteMenuItem); deleteMenuItem.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { deleteRecord(); } }); popupMenu.addSeparator(); JMenuItem editMenuItem = new JMenuItem("(E)", new ImageIcon(getClass().getResource("edit-4.png"))); editMenuItem.setMnemonic('E'); popupMenu.add(editMenuItem); editMenuItem.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { Record record = model.getRecord(table.convertRowIndexToModel(table.getSelectedRow())); showUpdateRecordDialog(record); } }); // ??popup menu table.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { if (disable) return; JTable table = (JTable) e.getSource(); Point point = e.getPoint(); int row = table.rowAtPoint(point); int col = table.columnAtPoint(e.getPoint()); if (SwingUtilities.isRightMouseButton(e)) { if (row >= 0 && col >= 0) { table.setRowSelectionInterval(row, row); } popupMenu.show(e.getComponent(), e.getX(), e.getY()); } else if (SwingUtilities.isLeftMouseButton(e)) { if (e.getClickCount() == 2) { if (row >= 0 && col >= 0) { // Record record = model.getRecord(table.convertRowIndexToModel(row)); // showUpdateRecordDialog(record); } } } } }); table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT) .put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "Enter"); table.getActionMap().put("Enter", new AbstractAction() { @Override public void actionPerformed(ActionEvent ae) { if (disable) return; //do something on JTable enter pressed int row = table.getSelectedRow(); if (row >= 0) { Record record = model.getRecord(table.convertRowIndexToModel(row)); showUpdateRecordDialog(record); } } }); } }