package org.myrobotlab.control; import java.awt.Color; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.datatransfer.DataFlavor; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JPanel; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; /** * source modified from: * http://bryanesmith.com/docs/drag-and-drop-java-5/DragAndDropPanelsDemo.java */ /** * * @author LunDev (github), Ma. Vo. (MyRobotlab) */ public class ServoOrchestratorGUI_middlemiddle_main { // References to the panels public ServoOrchestratorGUI_middlemiddle_panel[][] panels; // This is the panel that will hold everything. private final ServoOrchestratorGUI_middlemiddle_rootpanel rootPanel; // "border"-panels public ServoOrchestratorGUI_middlemiddle_panel[] prep; // "main"-panel private final JPanel middlemiddle; public final ServoOrchestratorGUI so_ref; public int panel_counter; /** * <p> * This represents the data that is transmitted in drag and drop. * </p> * <p> * In our limited case with only 1 type of dropped item, it will be a panel * object! * </p> * <p> * Note DataFlavor can represent more than classes -- easily text, images, * etc. * </p> */ private static DataFlavor dragAndDropPanelDataFlavor = null; /** * <p> * Returns (creating, if necessary) the DataFlavor representing * ServoOrchestratorGUI_middlemiddle_panel * </p> * * @return */ public static DataFlavor getDragAndDropPanelDataFlavor() throws Exception { // the commented (first one) is original and first it wotrked, then not // (???) // the second (uncommented) is my repair - don't know (???) // FIXME - maybe (???) // TODO - maybe a fix (???) // Lazy load/create the flavor if (dragAndDropPanelDataFlavor == null) { // dragAndDropPanelDataFlavor = new // DataFlavor(DataFlavor.javaJVMLocalObjectMimeType + // ";class=RandomDragAndDropPanel"); dragAndDropPanelDataFlavor = new DataFlavor(DataFlavor.javaJVMLocalObjectMimeType); } return dragAndDropPanelDataFlavor; } public ServoOrchestratorGUI_middlemiddle_main(final ServoOrchestratorGUI so_reft) { so_ref = so_reft; middlemiddle = new JPanel(); // Create the root panel and add to the main panel rootPanel = new ServoOrchestratorGUI_middlemiddle_rootpanel(ServoOrchestratorGUI_middlemiddle_main.this); rootPanel.setLayout(new GridBagLayout()); middlemiddle.add(rootPanel); panel_counter = 0; // Create a list to hold all the panels panels = new ServoOrchestratorGUI_middlemiddle_panel[so_ref.sizex][so_ref.sizey]; // "border"-panels prep = new ServoOrchestratorGUI_middlemiddle_panel[panels.length + panels[0].length]; for (int i = 0; i < prep.length; i++) { if (i < panels[0].length) { final int fi = i; panel_counter++; prep[i] = new ServoOrchestratorGUI_middlemiddle_panel("channel", panel_counter); prep[i].channel_id.setText(prep[i].id + ""); prep[i].channel_name.setText("Channel " + (i + 1)); prep[i].channel_settings.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent ae) { so_ref.externalcall_loadsettings(fi); } }); } else { panel_counter++; prep[i] = new ServoOrchestratorGUI_middlemiddle_panel("timesection", panel_counter); prep[i].timesection_id.setText(prep[i].id + ""); prep[i].timesection_headline.setText("TIMEUNIT " + (i - panels[0].length + 1)); } } prep[panels[0].length].setBackground(Color.red); // refresh the gui relayout(); } // Button public void externalcall_addPanel() { // Add the new panel to the array (on the first free space) // after that - relayout! boolean found = false; for (int i1 = 0; i1 < panels.length; i1++) { if (found) { break; } for (int i2 = 0; i2 < panels[i1].length; i2++) { if (found) { break; } if (panels[i1][i2] == null) { panel_counter++; ServoOrchestratorGUI_middlemiddle_panel p = new ServoOrchestratorGUI_middlemiddle_panel("servo", panel_counter); panels[i1][i2] = p; boolean later_externalcall_servopanelsettostartpos = false; boolean withgoal = false; p.servo_id.setText(p.id + ""); // TODO - make the channelid independent of the y-position // (i2) p.servo_channelid.setText("CH" + (i2 + 1)); int start = -1; int searchpos = i1 - 1; while (searchpos >= 0) { if (panels[searchpos][i2] == null) { searchpos--; } else { start = Integer.parseInt(panels[searchpos][i2].servo_goal.getText()); break; } } if (start == -1) { later_externalcall_servopanelsettostartpos = true; // it's the first panel in this row, // start changed with the externalcall below } p.servo_start.setText(start + ""); p.servo_goal.setText(start + ""); // this is probably useless int goal = -1; searchpos = i1 + 1; while (searchpos < panels.length) { if (panels[searchpos][i2] == null) { searchpos++; } else { goal = Integer.parseInt(panels[searchpos][i2].servo_start.getText()); break; } } p.servo_goal.setText(goal + ""); if (goal == -1) { p.servo_goal.setText(start + ""); if (start == -1) { withgoal = true; } } // min is changed with the externalcall below // max is changed with the externalcall below // TODO - add remaining attributes // (only button left) (others only fixes) (I think) found = true; final int fi1 = i1; final int fi2 = i2; final ServoOrchestratorGUI_middlemiddle_panel fp = p; p.servo_goal.getDocument().addDocumentListener(new DocumentListener() { public void adjust() { int i1 = fi1; int i2 = fi2; ServoOrchestratorGUI_middlemiddle_panel p = fp; int searchpos = i1 + 1; while (searchpos < panels.length) { if (panels[searchpos][i2] == null) { searchpos++; } else { panels[searchpos][i2].servo_start.setText(p.servo_goal.getText() + ""); break; } } } @Override public void changedUpdate(DocumentEvent e) { adjust(); } @Override public void insertUpdate(DocumentEvent e) { adjust(); } @Override public void removeUpdate(DocumentEvent e) { adjust(); } }); so_ref.externalcall_servopanelchangeinfo(i1, i2); if (later_externalcall_servopanelsettostartpos) { so_ref.externalcall_servopanelsettostartpos(i1, i2, withgoal); } } } } // Relayout the panels. relayout(); } public JPanel externalcall_getmiddlemiddle() { return middlemiddle; } public void externallcall_refreshsize() { // Copy all panels, because the arrays need to be re-created // the old stuff should be in it ServoOrchestratorGUI_middlemiddle_panel[][] panelsold = new ServoOrchestratorGUI_middlemiddle_panel[panels.length][panels[0].length]; for (int i = 0; i < panels.length; i++) { panelsold[i] = panels[i].clone(); } ServoOrchestratorGUI_middlemiddle_panel[] prepold = prep.clone(); // Create a list to hold all the panels panels = new ServoOrchestratorGUI_middlemiddle_panel[so_ref.sizex][so_ref.sizey]; for (int i1 = 0; i1 < panels.length; i1++) { if (i1 >= panelsold.length) { continue; } for (int i2 = 0; i2 < panels[0].length; i2++) { if (i2 >= panelsold[0].length) { continue; } panels[i1][i2] = panelsold[i1][i2]; } } // "border"-panels prep = new ServoOrchestratorGUI_middlemiddle_panel[panels.length + panels[0].length]; for (int i = 0; i < prep.length; i++) { if (i < panels[0].length) { final int fi = i; panel_counter++; prep[i] = new ServoOrchestratorGUI_middlemiddle_panel("channel", panel_counter); prep[i].channel_id.setText(prep[i].id + ""); prep[i].channel_name.setText("Channel " + (i + 1)); prep[i].channel_settings.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent ae) { so_ref.externalcall_loadsettings(fi); } }); prep[i].setBackground(Color.green); } else { panel_counter++; prep[i] = new ServoOrchestratorGUI_middlemiddle_panel("timesection", panel_counter); prep[i].timesection_id.setText(prep[i].id + ""); prep[i].timesection_headline.setText("TIMEUNIT " + (i - panels[0].length + 1)); prep[i].setBackground(Color.green); } } prep[panels[0].length].setBackground(Color.red); for (int i = 0; i < panelsold[0].length && i < panels[0].length; i++) { prep[i].channel_name.setText((prepold[i].channel_name.getText())); } // refresh the gui relayout(); } /** * <p> * Removes all components from our root panel and re-adds them. * </p> * <p> * This is important for two things: * </p> * <ul> * <li>Adding a new panel (user clicks on button)</li> * <li>Re-ordering panels (user drags and drops a panel to acceptable drop * target region)</li> * </ul> */ public void relayout() { // Create the constraints, and go ahead and set those // that don't change for components final GridBagConstraints gbc = new GridBagConstraints(); gbc.gridwidth = 1; gbc.gridheight = 1; gbc.anchor = GridBagConstraints.NORTH; gbc.weighty = 1.0; gbc.weightx = 1.0; gbc.fill = GridBagConstraints.NONE; gbc.insets = new Insets(0, 0, 0, 0); // Clear out all previously added items rootPanel.removeAll(); // Add the panels, if any & the "border"-panels for (int i1 = 0; i1 < panels.length + 1; i1++) { for (int i2 = 0; i2 < panels[0].length + 1; i2++) { if (i1 == 0 || i2 == 0) { if (i1 != 0 || i2 != 0) { gbc.gridx = i1; gbc.gridy = i2; int num = 0; if (i1 == 0) { num = i2 - 1; } else { num = panels[0].length - 1 + i1; } rootPanel.add(prep[num], gbc); } } else { ServoOrchestratorGUI_middlemiddle_panel p = panels[i1 - 1][i2 - 1]; gbc.gridx = i1; gbc.gridy = i2; if (p != null) { rootPanel.add(p, gbc); } } } } middlemiddle.validate(); middlemiddle.repaint(); } }