/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package Macros; import com.willwinder.ugs.nbp.lookup.CentralLookup; import com.willwinder.universalgcodesender.listeners.UGSEventListener; import com.willwinder.universalgcodesender.model.BackendAPI; import com.willwinder.universalgcodesender.model.UGSEvent; import com.willwinder.universalgcodesender.types.Macro; import com.willwinder.universalgcodesender.utils.Settings; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.GridLayout; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.nio.CharBuffer; import java.util.Arrays; import javax.swing.JButton; import javax.swing.JOptionPane; import javax.swing.table.DefaultTableModel; import org.netbeans.api.settings.ConvertAsProperties; import org.openide.awt.ActionID; import org.openide.awt.ActionReference; import org.openide.util.Exceptions; import org.openide.windows.TopComponent; import org.openide.util.NbBundle.Messages; /** * Top component which displays something. */ @ConvertAsProperties( dtd = "-//Macros//MacroWindow//EN", autostore = false ) @TopComponent.Description( preferredID = "MacroWindowTopComponent", //iconBase="SET/PATH/TO/ICON/HERE", persistenceType = TopComponent.PERSISTENCE_ALWAYS ) @TopComponent.Registration(mode = "visualizer", openAtStartup = false) @ActionID(category = "Window", id = "Macros.MacroWindowTopComponent") @ActionReference(path = "Menu/Window" /*, position = 333 */) @TopComponent.OpenActionRegistration( displayName = "#CTL_MacroWindowAction", preferredID = "MacroWindowTopComponent" ) @Messages({ "CTL_MacroWindowAction=Macros", "CTL_MacroWindowTopComponent=MacroWindow Window", "HINT_MacroWindowTopComponent=This is a MacroWindow window" }) public final class MacroWindowTopComponent extends TopComponent implements UGSEventListener{ // This is used in most functions, so cache it here. DefaultTableModel model; private int editRow = -1; private final BackendAPI backend; private boolean isSending; private static final String SEPARATOR = "|"; private static final String UGS_MACROFILENAMe = "ugsMacros.txt"; private Settings settings; public MacroWindowTopComponent() { initComponents(); setName(Bundle.CTL_MacroWindowTopComponent()); setToolTipText(Bundle.HINT_MacroWindowTopComponent()); this.macroPanel.setLayout(new GridLayout(6,4, 20, 20)); settings = CentralLookup.getDefault().lookup(Settings.class); backend = CentralLookup.getDefault().lookup(BackendAPI.class); backend.addUGSEventListener(this); } /** * This method is called from within the constructor to initialize the form. * WARNING: Do NOT modify this code. The content of this method is always * regenerated by the Form Editor. */ // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents private void initComponents() { tabbedPanel = new javax.swing.JTabbedPane(); macroPanel = new javax.swing.JPanel(); settingsPanel = new javax.swing.JPanel(); editPanel = new javax.swing.JPanel(); titleLabel = new javax.swing.JLabel(); titleTextField = new javax.swing.JTextField(); gcodeLabel = new javax.swing.JLabel(); gcodeTextField = new javax.swing.JTextField(); newMacroButton = new javax.swing.JButton(); updateMacroButton = new javax.swing.JButton(); moveUpButton = new javax.swing.JButton(); deleteButton = new javax.swing.JButton(); editButton = new javax.swing.JButton(); moveDownButton = new javax.swing.JButton(); tableScrollPane = new javax.swing.JScrollPane(); macroTable = new javax.swing.JTable(); tabbedPanel.setBackground(new java.awt.Color(238, 238, 238)); macroPanel.setBorder(javax.swing.BorderFactory.createEmptyBorder(10, 10, 10, 10)); javax.swing.GroupLayout macroPanelLayout = new javax.swing.GroupLayout(macroPanel); macroPanel.setLayout(macroPanelLayout); macroPanelLayout.setHorizontalGroup( macroPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGap(0, 867, Short.MAX_VALUE) ); macroPanelLayout.setVerticalGroup( macroPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGap(0, 504, Short.MAX_VALUE) ); tabbedPanel.addTab(org.openide.util.NbBundle.getMessage(MacroWindowTopComponent.class, "MacroWindowTopComponent.macroPanel.TabConstraints.tabTitle"), macroPanel); // NOI18N editPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(MacroWindowTopComponent.class, "MacroWindowTopComponent.editPanel.border.title"))); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(titleLabel, org.openide.util.NbBundle.getMessage(MacroWindowTopComponent.class, "MacroWindowTopComponent.titleLabel.text")); // NOI18N titleTextField.setText(org.openide.util.NbBundle.getMessage(MacroWindowTopComponent.class, "MacroWindowTopComponent.titleTextField.text")); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(gcodeLabel, org.openide.util.NbBundle.getMessage(MacroWindowTopComponent.class, "MacroWindowTopComponent.gcodeLabel.text")); // NOI18N gcodeTextField.setText(org.openide.util.NbBundle.getMessage(MacroWindowTopComponent.class, "MacroWindowTopComponent.gcodeTextField.text")); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(newMacroButton, org.openide.util.NbBundle.getMessage(MacroWindowTopComponent.class, "MacroWindowTopComponent.newMacroButton.text")); // NOI18N newMacroButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { newMacroButtonActionPerformed(evt); } }); org.openide.awt.Mnemonics.setLocalizedText(updateMacroButton, org.openide.util.NbBundle.getMessage(MacroWindowTopComponent.class, "MacroWindowTopComponent.updateMacroButton.text")); // NOI18N updateMacroButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { updateMacroButtonActionPerformed(evt); } }); javax.swing.GroupLayout editPanelLayout = new javax.swing.GroupLayout(editPanel); editPanel.setLayout(editPanelLayout); editPanelLayout.setHorizontalGroup( editPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(editPanelLayout.createSequentialGroup() .addGroup(editPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(gcodeLabel) .addComponent(titleLabel)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addGroup(editPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(titleTextField) .addComponent(gcodeTextField)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(editPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) .addComponent(updateMacroButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(newMacroButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addContainerGap()) ); editPanelLayout.setVerticalGroup( editPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(editPanelLayout.createSequentialGroup() .addGroup(editPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(titleLabel) .addComponent(titleTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(newMacroButton)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(editPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(gcodeLabel) .addComponent(gcodeTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(updateMacroButton)) .addGap(0, 10, Short.MAX_VALUE)) ); moveUpButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons/glyphicons-601-chevron-up.png"))); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(moveUpButton, org.openide.util.NbBundle.getMessage(MacroWindowTopComponent.class, "MacroWindowTopComponent.moveUpButton.text")); // NOI18N moveUpButton.setToolTipText(org.openide.util.NbBundle.getMessage(MacroWindowTopComponent.class, "MacroWindowTopComponent.moveUpButton.toolTipText")); // NOI18N moveUpButton.setMinimumSize(new java.awt.Dimension(58, 31)); moveUpButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { moveUpButtonActionPerformed(evt); } }); deleteButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons/glyphicons-208-remove.png"))); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(deleteButton, org.openide.util.NbBundle.getMessage(MacroWindowTopComponent.class, "MacroWindowTopComponent.deleteButton.text")); // NOI18N deleteButton.setToolTipText(org.openide.util.NbBundle.getMessage(MacroWindowTopComponent.class, "MacroWindowTopComponent.deleteButton.toolTipText")); // NOI18N deleteButton.setMaximumSize(new java.awt.Dimension(58, 31)); deleteButton.setMinimumSize(new java.awt.Dimension(58, 31)); deleteButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { deleteButtonActionPerformed(evt); } }); editButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons/glyphicons-151-edit.png"))); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(editButton, org.openide.util.NbBundle.getMessage(MacroWindowTopComponent.class, "MacroWindowTopComponent.editButton.text")); // NOI18N editButton.setToolTipText(org.openide.util.NbBundle.getMessage(MacroWindowTopComponent.class, "MacroWindowTopComponent.editButton.toolTipText")); // NOI18N editButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { editButtonActionPerformed(evt); } }); moveDownButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons/glyphicons-602-chevron-down.png"))); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(moveDownButton, org.openide.util.NbBundle.getMessage(MacroWindowTopComponent.class, "MacroWindowTopComponent.moveDownButton.text")); // NOI18N moveDownButton.setToolTipText(org.openide.util.NbBundle.getMessage(MacroWindowTopComponent.class, "MacroWindowTopComponent.moveDownButton.toolTipText")); // NOI18N moveDownButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { moveDownButtonActionPerformed(evt); } }); macroTable.setModel(new javax.swing.table.DefaultTableModel( new Object [][] { }, new String [] { "Title", "Gcode" } ) { Class[] types = new Class [] { java.lang.String.class, java.lang.String.class }; boolean[] canEdit = new boolean [] { false, false }; public Class getColumnClass(int columnIndex) { return types [columnIndex]; } public boolean isCellEditable(int rowIndex, int columnIndex) { return canEdit [columnIndex]; } }); macroTable.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION); tableScrollPane.setViewportView(macroTable); javax.swing.GroupLayout settingsPanelLayout = new javax.swing.GroupLayout(settingsPanel); settingsPanel.setLayout(settingsPanelLayout); settingsPanelLayout.setHorizontalGroup( settingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(editPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addGroup(settingsPanelLayout.createSequentialGroup() .addComponent(tableScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 813, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(settingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) .addComponent(moveUpButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(deleteButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(editButton, javax.swing.GroupLayout.DEFAULT_SIZE, 68, Short.MAX_VALUE) .addComponent(moveDownButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) ); settingsPanelLayout.setVerticalGroup( settingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(settingsPanelLayout.createSequentialGroup() .addComponent(editPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(settingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(settingsPanelLayout.createSequentialGroup() .addComponent(moveUpButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(deleteButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(editButton) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(moveDownButton) .addContainerGap()) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, settingsPanelLayout.createSequentialGroup() .addGap(0, 0, Short.MAX_VALUE) .addComponent(tableScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))) ); tabbedPanel.addTab(org.openide.util.NbBundle.getMessage(MacroWindowTopComponent.class, "MacroWindowTopComponent.settingsPanel.TabConstraints.tabTitle"), settingsPanel); // NOI18N javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(tabbedPanel) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(tabbedPanel) ); }// </editor-fold>//GEN-END:initComponents private void moveUpButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_moveUpButtonActionPerformed // TODO add your handling code here: int[] selectedRows = this.macroTable.getSelectedRows(); // Exit early if nothing is selected. if (selectedRows.length == 0) return; Arrays.sort(selectedRows); // Exit early if the selected range can't move. if (selectedRows[0] == 0) return; for (int i = 0; i < selectedRows.length; i++) { selectedRows[i] = this.moveRow(selectedRows[i], -1); } int first = selectedRows[0]; int last = selectedRows[selectedRows.length-1]; this.macroTable.setRowSelectionInterval(first, last); updateMacroPanel(); }//GEN-LAST:event_moveUpButtonActionPerformed private void updateMacroButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_updateMacroButtonActionPerformed if (!"".equals(this.gcodeTextField.getText()) && !"".equals(this.titleTextField.getText())) { if (this.editRow == -1) { addRow(this.titleTextField.getText(), this.gcodeTextField.getText()); } else { model.setValueAt(this.titleTextField.getText(), this.editRow, 0); model.setValueAt(this.gcodeTextField.getText(), this.editRow, 1); this.editRow = -1; } emptyTextFields(); updateMacroPanel(); } }//GEN-LAST:event_updateMacroButtonActionPerformed private void addRow(String title, String gcode) { model.addRow(new Object[]{ title, gcode, false }); } private void emptyTextFields() { this.titleTextField.setText(""); this.gcodeTextField.setText(""); } private void deleteButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteButtonActionPerformed int[] selectedRows = this.macroTable.getSelectedRows(); if (selectedRows.length == 0) return; Arrays.sort(selectedRows); for (int i = selectedRows.length - 1; i >= 0; i--) { int row = selectedRows[i]; this.model.removeRow(row); this.model.fireTableRowsDeleted(row, row); } updateMacroPanel(); }//GEN-LAST:event_deleteButtonActionPerformed private void moveDownButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_moveDownButtonActionPerformed int[] selectedRows = this.macroTable.getSelectedRows(); // Exit early if nothing is selected. if (selectedRows.length == 0) return; Arrays.sort(selectedRows); // Exit early if the selected range can't move. if (selectedRows[selectedRows.length-1] == this.macroTable.getRowCount()) return; for (int i = selectedRows.length - 1; i >= 0; i--) { selectedRows[i] = this.moveRow(selectedRows[i], 1); } this.macroTable.setRowSelectionInterval(selectedRows[0], selectedRows[selectedRows.length-1]); updateMacroPanel(); }//GEN-LAST:event_moveDownButtonActionPerformed private void editButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_editButtonActionPerformed // TODO add your handling code here: this.editRow = this.macroTable.getSelectedRow(); if (this.editRow > -1) { this.titleTextField.setText((String) this.model.getValueAt(this.editRow, 0)); this.gcodeTextField.setText((String) this.model.getValueAt(this.editRow, 1)); } }//GEN-LAST:event_editButtonActionPerformed private void newMacroButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_newMacroButtonActionPerformed emptyTextFields(); this.editRow = -1; }//GEN-LAST:event_newMacroButtonActionPerformed private void updateMacroPanel() { // TODO add your handling code here: this.macroPanel.removeAll(); String fileContent = ""; int rows = this.model.getRowCount(); int cols = this.model.getColumnCount(); for(int i = 0; i < rows; i++) { String buttonTitle = (String) this.model.getValueAt(i, 0); String buttonGcode = (String) this.model.getValueAt(i, 1); JButton button = new JButton(buttonTitle); button.setToolTipText(buttonGcode); button.setEnabled(!isSending && backend.isConnected()); button.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { macroButtonActionPerformed(evt); } }); //button.setMinimumSize(new Dimension(30, 30)); this.macroPanel.add(button); settings.updateMacro(i, buttonTitle, "", buttonGcode); } } private void macroButtonActionPerformed(java.awt.event.ActionEvent evt) { JButton macroButton = (JButton) evt.getSource(); String gcode = macroButton.getToolTipText(); String[] gCodeCommands = gcode.split(";"); try { for (int i = 0; i < gCodeCommands.length; i++) { backend.sendGcodeCommand(gCodeCommands[i]); } } catch (Exception ex) { Exceptions.printStackTrace(ex); } } // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton deleteButton; private javax.swing.JButton editButton; private javax.swing.JPanel editPanel; private javax.swing.JLabel gcodeLabel; private javax.swing.JTextField gcodeTextField; private javax.swing.JPanel macroPanel; private javax.swing.JTable macroTable; private javax.swing.JButton moveDownButton; private javax.swing.JButton moveUpButton; private javax.swing.JButton newMacroButton; private javax.swing.JPanel settingsPanel; private javax.swing.JTabbedPane tabbedPanel; private javax.swing.JScrollPane tableScrollPane; private javax.swing.JLabel titleLabel; private javax.swing.JTextField titleTextField; private javax.swing.JButton updateMacroButton; // End of variables declaration//GEN-END:variables @Override public void componentOpened() { // TODO add custom code on component opening this.model = (DefaultTableModel)this.macroTable.getModel(); loadSettings(); updateMacroPanel(); } private void loadSettings() { int index = settings.getLastMacroIndex(); if (settings.getLastMacroIndex() > -1) { for (int i = 0; i <= settings.getLastMacroIndex(); i++) { Macro macro = settings.getMacro(i); addRow(macro.getName(), macro.getGcode()); } } } @Override public void componentClosed() { // TODO add custom code on component closing } void writeProperties(java.util.Properties p) { // better to version settings since initial version as advocated at // http://wiki.apidesign.org/wiki/PropertyFiles p.setProperty("version", "1.0"); // TODO store your settings } void readProperties(java.util.Properties p) { String version = p.getProperty("version"); // TODO read your settings according to their version } /** * Move a given row by some offset. If the offset would move the row outside * of the current table size, the row is not moved. * @param row row to move. * @param offset how far to move row. * @return location of row after move. */ private int moveRow(int row, int offset) { int dest = row + offset; if (dest < 0 || dest >= model.getRowCount()) { return row; } model.moveRow(row, row, dest); return dest; } @Override public void UGSEvent(com.willwinder.universalgcodesender.model.UGSEvent ugse) { if (ugse.isStateChangeEvent()) { isSending = backend.isSending(); } updateMacroPanel(); } }