/* Copywrite 2016 Will Winder This file is part of Universal Gcode Sender (UGS). UGS 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. UGS 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 UGS. If not, see <http://www.gnu.org/licenses/>. */ package com.willwinder.universalgcodesender.uielements.helpers; import com.willwinder.universalgcodesender.i18n.Localization; import com.willwinder.universalgcodesender.listeners.UGSEventListener; import com.willwinder.universalgcodesender.model.BackendAPI; import com.willwinder.universalgcodesender.model.UGSEvent; import com.willwinder.universalgcodesender.uielements.actions.ConnectDisconnectAction; import com.willwinder.universalgcodesender.utils.CommUtils; import com.willwinder.universalgcodesender.utils.FirmwareUtils; import com.willwinder.universalgcodesender.utils.Settings; import java.awt.Component; import java.util.List; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JLabel; import javax.swing.JPanel; import org.apache.commons.lang3.StringUtils; import static com.willwinder.universalgcodesender.model.UGSEvent.ControlState.COMM_DISCONNECTED; import static com.willwinder.universalgcodesender.utils.GUIHelpers.displayErrorDialog; /** * @author wwinder */ public abstract class AbstractConnectionPanel extends JPanel implements UGSEventListener { protected final BackendAPI backend; // Icon paths static private final String REFRESH_ICON = "/resources/icons/refresh.gif"; static private final String CONNECTED_ICON = "/resources/icons/connect.png"; static private final String DISCONNECTED_ICON = "/resources/icons/disconnect.gif"; // Icon resources private final ImageIcon refreshIcon = new ImageIcon(getClass().getResource(REFRESH_ICON)); private final ImageIcon connectedIcon = new ImageIcon(getClass().getResource(CONNECTED_ICON)); private final ImageIcon disconnectedIcon = new ImageIcon(getClass().getResource(DISCONNECTED_ICON)); // Localized labels protected final JLabel portLabel = new JLabel(Localization.getString("mainWindow.swing.portLabel")); protected final JLabel baudLabel = new JLabel(Localization.getString("mainWindow.swing.baudLabel")); protected final JLabel firmwareLabel = new JLabel(Localization.getString("mainWindow.swing.firmwareLabel")); // Combo boxes, these need to be synchronized with Settings protected final JComboBox<String> firmwareCombo = new JComboBox<>(); protected final JComboBox<String> portCombo = new JComboBox<>(); protected final JComboBox<String> baudCombo = new JComboBox<>(); protected final JButton refreshButton = new JButton(); protected final JButton connectDisconnectButton = new JButton(); private boolean initializing = true; public AbstractConnectionPanel(BackendAPI backend) { this.backend = backend; this.backend.addUGSEventListener(this); loadFirmwareSelector(); initComponents(); initializing = false; updateComponents(); } /** * Implementing classes should define the layout of all desired components * in this method. It will be called once during construction. */ protected abstract void layoutComponents(); @Override public void UGSEvent(UGSEvent evt) { // If a setting has changed elsewhere, update the combo boxes. if (evt.isSettingChangeEvent()) { System.out.println("Setting changed"); updateComponents(); } // if the state has changed, check if the else if (evt.isStateChangeEvent()) { if (evt.getControlState() == COMM_DISCONNECTED) { connectDisconnectButton.setIcon(disconnectedIcon); firmwareCombo.setEnabled(true); baudCombo.setEnabled(true); portCombo.setEnabled(true); refreshButton.setEnabled(true); } else { connectDisconnectButton.setIcon(connectedIcon); firmwareCombo.setEnabled(false); baudCombo.setEnabled(false); portCombo.setEnabled(false); refreshButton.setEnabled(false); } } } private void initComponents() { // People should be able to type in custom values. portCombo.setEditable(true); baudCombo.setEditable(true); // Baud rate options. baudCombo.setModel(new javax.swing.DefaultComboBoxModel<>(new String[]{"2400", "4800", "9600", "19200", "38400", "57600", "115200", "230400"})); baudCombo.setSelectedIndex(6); baudCombo.setToolTipText("Select baudrate to use for the serial port."); // Hookup button actions refreshButton.addActionListener(evt -> loadPortSelector()); connectDisconnectButton.setAction(new ConnectDisconnectAction(backend)); // Customize appearance refreshButton.setIcon(refreshIcon); connectDisconnectButton.setIcon(disconnectedIcon); connectDisconnectButton.setBorderPainted(false); // Hookup change reporters firmwareCombo.addActionListener(a -> componentUpdated(firmwareCombo)); portCombo.addActionListener(a -> componentUpdated(portCombo)); baudCombo.addActionListener(a -> componentUpdated(baudCombo)); // Layout of components by implementing class. layoutComponents(); } synchronized private void updateComponents() { if (initializing) return; initializing = true; Settings s = backend.getSettings(); portCombo.setSelectedItem(s.getPort()); baudCombo.setSelectedItem(s.getPortRate()); firmwareCombo.setSelectedItem(s.getFirmwareVersion()); initializing = false; } private void componentUpdated(Component c) { if (initializing) return; if (c == portCombo) { backend.getSettings().setPort(portCombo.getSelectedItem() + ""); } else if (c == baudCombo) { backend.getSettings().setPortRate(baudCombo.getSelectedItem() + ""); } else if (c == firmwareCombo) { backend.getSettings().setFirmwareVersion(firmwareCombo.getSelectedItem() + ""); } } private void loadPortSelector() { portCombo.removeAllItems(); String[] portList = CommUtils.getSerialPortList(); if (portList.length < 1) { if (backend.getSettings().isShowSerialPortWarning()) { displayErrorDialog(Localization.getString("mainWindow.error.noSerialPort")); } } else { for (String port : portList) { if (StringUtils.isNotEmpty(port)) { System.out.println(">>>>>> "); portCombo.addItem(port); } } portCombo.setSelectedIndex(0); portCombo.repaint(); } } private void loadFirmwareSelector() { firmwareCombo.removeAllItems(); List<String> firmwareList = FirmwareUtils.getFirmwareList(); if (firmwareList.size() < 1) { displayErrorDialog(Localization.getString("mainWindow.error.noFirmware")); } else { firmwareList.forEach(firmwareCombo::addItem); } } }