|
@@ -6,7 +6,6 @@ import java.awt.Container;
|
|
import java.awt.Dimension;
|
|
import java.awt.Dimension;
|
|
import java.math.RoundingMode;
|
|
import java.math.RoundingMode;
|
|
import java.text.NumberFormat;
|
|
import java.text.NumberFormat;
|
|
-import java.util.ArrayList;
|
|
|
|
import java.util.Collection;
|
|
import java.util.Collection;
|
|
import java.util.HashSet;
|
|
import java.util.HashSet;
|
|
import java.util.List;
|
|
import java.util.List;
|
|
@@ -15,7 +14,6 @@ import java.util.Optional;
|
|
import java.util.Set;
|
|
import java.util.Set;
|
|
import java.util.stream.Collectors;
|
|
import java.util.stream.Collectors;
|
|
import java.util.stream.Stream;
|
|
import java.util.stream.Stream;
|
|
-
|
|
|
|
import javax.swing.BorderFactory;
|
|
import javax.swing.BorderFactory;
|
|
import javax.swing.Box;
|
|
import javax.swing.Box;
|
|
import javax.swing.BoxLayout;
|
|
import javax.swing.BoxLayout;
|
|
@@ -39,11 +37,20 @@ import ui.controller.Control;
|
|
import ui.view.component.TrippleCheckBox;
|
|
import ui.view.component.TrippleCheckBox;
|
|
import ui.view.component.TrippleCheckBox.State;
|
|
import ui.view.component.TrippleCheckBox.State;
|
|
import utility.ImageImport;
|
|
import utility.ImageImport;
|
|
|
|
+import utility.Pool;
|
|
import utility.events.Action;
|
|
import utility.events.Action;
|
|
import utility.events.SimpleDocumentListener;
|
|
import utility.events.SimpleDocumentListener;
|
|
|
|
|
|
public class InspectorTable extends JPanel {
|
|
public class InspectorTable extends JPanel {
|
|
- private List<ElementRow> elementRows = new ArrayList<ElementRow>();
|
|
|
|
|
|
+ private Pool<ElementRow> rowPool = new Pool<ElementRow>() {
|
|
|
|
+ @Override
|
|
|
|
+ public ElementRow create() {
|
|
|
|
+ return new ElementRow();
|
|
|
|
+ }
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ private final int maxDisplayedRowsNumber = 1000;
|
|
|
|
+
|
|
private Control control;
|
|
private Control control;
|
|
private final int columnHeight = 20;
|
|
private final int columnHeight = 20;
|
|
//UI
|
|
//UI
|
|
@@ -68,9 +75,12 @@ public class InspectorTable extends JPanel {
|
|
generateHeader();
|
|
generateHeader();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
private void init() {
|
|
private void init() {
|
|
MigLayout layout = new MigLayout("insets 0,gap 0,wrap 7", // Layout Constraints
|
|
MigLayout layout = new MigLayout("insets 0,gap 0,wrap 7", // Layout Constraints
|
|
- "[][fill, grow][][fill, grow][fill, grow][][]", // Column constraints
|
|
|
|
|
|
+ "[][fill, grow][fill][fill, grow][fill, grow][][fill]", // Column constraints
|
|
"[25!][20:20:20]"); // Row constraints
|
|
"[25!][20:20:20]"); // Row constraints
|
|
this.setLayout(layout);
|
|
this.setLayout(layout);
|
|
initSelectAllCheckBox();
|
|
initSelectAllCheckBox();
|
|
@@ -107,18 +117,14 @@ public class InspectorTable extends JPanel {
|
|
switch (selectAllCheckBox.getSelectionState()) {
|
|
switch (selectAllCheckBox.getSelectionState()) {
|
|
case mid_state_selection:
|
|
case mid_state_selection:
|
|
case selected: {
|
|
case selected: {
|
|
- for (ElementRow row : elementRows) {
|
|
|
|
- row.setSelected(false);
|
|
|
|
- }
|
|
|
|
|
|
+ rowPool.getBorrowedStream().forEach(row -> row.setSelected(false));
|
|
duplicateButton.setEnabled(false);
|
|
duplicateButton.setEnabled(false);
|
|
deleteButton.setEnabled(false);
|
|
deleteButton.setEnabled(false);
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
case unselected:
|
|
case unselected:
|
|
- if(!elementRows.isEmpty()) {
|
|
|
|
- for (ElementRow row : elementRows) {
|
|
|
|
- row.setSelected(true);
|
|
|
|
- }
|
|
|
|
|
|
+ if(rowPool.getBorrowedCount() == 0) {
|
|
|
|
+ rowPool.getBorrowedStream().forEach(row -> row.setSelected(true));
|
|
duplicateButton.setEnabled(true);
|
|
duplicateButton.setEnabled(true);
|
|
deleteButton.setEnabled(true);
|
|
deleteButton.setEnabled(true);
|
|
}
|
|
}
|
|
@@ -158,11 +164,11 @@ public class InspectorTable extends JPanel {
|
|
duplicateButton.setIcon(new ImageIcon(ImageImport.loadImage("Images/duplicate.png", 16, 16)));
|
|
duplicateButton.setIcon(new ImageIcon(ImageImport.loadImage("Images/duplicate.png", 16, 16)));
|
|
duplicateButton.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
|
|
duplicateButton.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
|
|
duplicateButton.addActionListener(clicked -> {
|
|
duplicateButton.addActionListener(clicked -> {
|
|
- for (ElementRow row : elementRows) {
|
|
|
|
|
|
+ rowPool.getBorrowedStream().forEach(row -> {
|
|
if(row.isSelected()) {
|
|
if(row.isSelected()) {
|
|
row.element.parentObject.addElement(new HolonElement(row.element));
|
|
row.element.parentObject.addElement(new HolonElement(row.element));
|
|
}
|
|
}
|
|
- }
|
|
|
|
|
|
+ });
|
|
control.calculateStateAndVisualForCurrentTimeStep();
|
|
control.calculateStateAndVisualForCurrentTimeStep();
|
|
update_ui();
|
|
update_ui();
|
|
});
|
|
});
|
|
@@ -171,11 +177,11 @@ public class InspectorTable extends JPanel {
|
|
deleteButton.setIcon(new ImageIcon(ImageImport.loadImage("Images/minus.png", 16, 16)));
|
|
deleteButton.setIcon(new ImageIcon(ImageImport.loadImage("Images/minus.png", 16, 16)));
|
|
deleteButton.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
|
|
deleteButton.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
|
|
deleteButton.addActionListener(clicked -> {
|
|
deleteButton.addActionListener(clicked -> {
|
|
- for (ElementRow row : elementRows) {
|
|
|
|
|
|
+ rowPool.getBorrowedStream().forEach(row -> {
|
|
if(row.isSelected()) {
|
|
if(row.isSelected()) {
|
|
row.element.parentObject.removeElement(row.element);
|
|
row.element.parentObject.removeElement(row.element);
|
|
}
|
|
}
|
|
- }
|
|
|
|
|
|
+ });
|
|
control.calculateStateAndVisualForCurrentTimeStep();
|
|
control.calculateStateAndVisualForCurrentTimeStep();
|
|
update_ui();
|
|
update_ui();
|
|
});
|
|
});
|
|
@@ -196,19 +202,28 @@ public class InspectorTable extends JPanel {
|
|
//clone for concurrency
|
|
//clone for concurrency
|
|
Set<AbstractCanvasObject> selection = new HashSet<>(control.getModel().getSelectedObjects());
|
|
Set<AbstractCanvasObject> selection = new HashSet<>(control.getModel().getSelectedObjects());
|
|
populateRowsThread = new Thread(() -> {
|
|
populateRowsThread = new Thread(() -> {
|
|
|
|
+ // time passes
|
|
List<HolonElement> elementList = extractElements(selection).toList();
|
|
List<HolonElement> elementList = extractElements(selection).toList();
|
|
|
|
+ int numberOfRows = elementList.size();
|
|
this.removeAll();
|
|
this.removeAll();
|
|
- elementRows.clear();
|
|
|
|
- // TODO Pooling
|
|
|
|
|
|
+ rowPool.clear();
|
|
generateHeader();
|
|
generateHeader();
|
|
for(HolonElement element : elementList)
|
|
for(HolonElement element : elementList)
|
|
{
|
|
{
|
|
- if(abortThread) break;
|
|
|
|
- elementRows.add(new ElementRow(element));
|
|
|
|
- revalidate();
|
|
|
|
- repaint();
|
|
|
|
|
|
+ ElementRow row = rowPool.get();
|
|
|
|
+ row.setElement(element);
|
|
|
|
+ }
|
|
|
|
+ rowPool.getBorrowedStream().limit(maxDisplayedRowsNumber).takeWhile(row -> !abortThread).forEach(row -> {
|
|
|
|
+ row.addContainerToInspector();
|
|
|
|
+ });
|
|
|
|
+ if(numberOfRows > maxDisplayedRowsNumber) {
|
|
|
|
+ int remaining = elementList.size() - maxDisplayedRowsNumber;
|
|
|
|
+ JLabel remainingLabel = new JLabel(remaining + " more...");
|
|
|
|
+ remainingLabel.setForeground(Color.gray);
|
|
|
|
+ this.add(remainingLabel, "span");
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
this.add(buttonPanel, "span");
|
|
this.add(buttonPanel, "span");
|
|
boolean isAtLeastOneHolonObjectSelected =
|
|
boolean isAtLeastOneHolonObjectSelected =
|
|
control.getModel().getSelectedObjects().stream().anyMatch(object -> object instanceof HolonObject);
|
|
control.getModel().getSelectedObjects().stream().anyMatch(object -> object instanceof HolonObject);
|
|
@@ -226,13 +241,13 @@ public class InspectorTable extends JPanel {
|
|
|
|
|
|
|
|
|
|
private void updateElementSelection() {
|
|
private void updateElementSelection() {
|
|
- Set<HolonElement> eleSet = elementRows.stream().filter(ele -> ele.isSelected()).map(row -> row.element).collect(Collectors.toSet());
|
|
|
|
|
|
+ Set<HolonElement> eleSet = rowPool.getBorrowedStream().filter(ele -> ele.isSelected()).map(row -> row.element).collect(Collectors.toSet());
|
|
this.OnElementSelectionChanged.broadcast(eleSet);
|
|
this.OnElementSelectionChanged.broadcast(eleSet);
|
|
}
|
|
}
|
|
|
|
|
|
private void updateButtonAppearance() {
|
|
private void updateButtonAppearance() {
|
|
- long count = elementRows.stream().filter(ele -> ele.isSelected()).count();
|
|
|
|
- if (count == elementRows.size()) {
|
|
|
|
|
|
+ long count = rowPool.getBorrowedStream().filter(ele -> ele.isSelected()).count();
|
|
|
|
+ if (count == rowPool.getBorrowedCount()) {
|
|
selectAllCheckBox.setSelectionState(State.selected);
|
|
selectAllCheckBox.setSelectionState(State.selected);
|
|
} else if (count == 0) {
|
|
} else if (count == 0) {
|
|
selectAllCheckBox.setSelectionState(State.unselected);
|
|
selectAllCheckBox.setSelectionState(State.unselected);
|
|
@@ -257,17 +272,24 @@ public class InspectorTable extends JPanel {
|
|
|
|
|
|
|
|
|
|
private class ElementRow {
|
|
private class ElementRow {
|
|
- HolonElement element;
|
|
|
|
|
|
+ private HolonElement element = null;
|
|
|
|
+ private Container[] cellsInRow = new Container[7];
|
|
|
|
+ //TextBoxes
|
|
|
|
+ private JTextField elementNameTextField;
|
|
private JCheckBox selectionBox;
|
|
private JCheckBox selectionBox;
|
|
- Container[] cellsInRow = new Container[7];
|
|
|
|
-
|
|
|
|
- ElementRow(HolonElement element) {
|
|
|
|
- this.element = element;
|
|
|
|
|
|
+ private JTextField idObjectTextField;
|
|
|
|
+ private JFormattedTextField energyTextField;
|
|
|
|
+ private JComboBox<Priority> comboBox;
|
|
|
|
+ private JCheckBox activeCheckBox;
|
|
|
|
+ private JTextField objectNameTextField;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ public ElementRow() {
|
|
this.createEditFields();
|
|
this.createEditFields();
|
|
- addContainerToInspector();
|
|
|
|
}
|
|
}
|
|
|
|
|
|
- private void addContainerToInspector() {
|
|
|
|
|
|
+ public void addContainerToInspector() {
|
|
for (Container cell : cellsInRow) {
|
|
for (Container cell : cellsInRow) {
|
|
InspectorTable.this.add(cell);
|
|
InspectorTable.this.add(cell);
|
|
}
|
|
}
|
|
@@ -285,6 +307,20 @@ public class InspectorTable extends JPanel {
|
|
return selectionBox.isSelected();
|
|
return selectionBox.isSelected();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ public void setElement(HolonElement element) {
|
|
|
|
+ this.element = element;
|
|
|
|
+ selectionBox.setSelected(false);
|
|
|
|
+ objectNameTextField.setText(this.element.parentObject.getName());
|
|
|
|
+ idObjectTextField.setText(Integer.toString(this.element.parentObject.getId()));
|
|
|
|
+ elementNameTextField.setText(this.element.getEleName());
|
|
|
|
+ energyTextField.setValue(this.element.getEnergy());
|
|
|
|
+ comboBox.setSelectedItem(this.element.getPriority());
|
|
|
|
+ activeCheckBox.setSelected(this.element.isActive());
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
private void createEditFields() {
|
|
private void createEditFields() {
|
|
// Selected
|
|
// Selected
|
|
JPanel selectedColumnPanel = new JPanel(new BorderLayout());
|
|
JPanel selectedColumnPanel = new JPanel(new BorderLayout());
|
|
@@ -305,20 +341,20 @@ public class InspectorTable extends JPanel {
|
|
cellsInRow[0] = selectedColumnPanel;
|
|
cellsInRow[0] = selectedColumnPanel;
|
|
|
|
|
|
// ObjectName and ID
|
|
// ObjectName and ID
|
|
- JTextField objectNameTextField = new JTextField(this.element.parentObject.getName());
|
|
|
|
|
|
+ objectNameTextField = new JTextField();
|
|
objectNameTextField.getDocument().addDocumentListener((SimpleDocumentListener) e -> {
|
|
objectNameTextField.getDocument().addDocumentListener((SimpleDocumentListener) e -> {
|
|
this.element.parentObject.setName(objectNameTextField.getText());
|
|
this.element.parentObject.setName(objectNameTextField.getText());
|
|
});
|
|
});
|
|
objectNameTextField.addActionListener(ae -> update_ui());
|
|
objectNameTextField.addActionListener(ae -> update_ui());
|
|
cellsInRow[1] = objectNameTextField;
|
|
cellsInRow[1] = objectNameTextField;
|
|
- JTextField idObjectTextField = new JTextField(Integer.toString(this.element.parentObject.getId()));
|
|
|
|
|
|
+ idObjectTextField = new JTextField();
|
|
idObjectTextField.setMinimumSize(idObjectTextField.getPreferredSize());
|
|
idObjectTextField.setMinimumSize(idObjectTextField.getPreferredSize());
|
|
idObjectTextField.setBackground(Color.white);
|
|
idObjectTextField.setBackground(Color.white);
|
|
idObjectTextField.setEditable(false);
|
|
idObjectTextField.setEditable(false);
|
|
idObjectTextField.setEnabled(false);
|
|
idObjectTextField.setEnabled(false);
|
|
cellsInRow[2] = idObjectTextField;
|
|
cellsInRow[2] = idObjectTextField;
|
|
// Name
|
|
// Name
|
|
- JTextField elementNameTextField = new JTextField(this.element.getEleName());
|
|
|
|
|
|
+ elementNameTextField = new JTextField();
|
|
elementNameTextField.getDocument().addDocumentListener((SimpleDocumentListener) e -> {
|
|
elementNameTextField.getDocument().addDocumentListener((SimpleDocumentListener) e -> {
|
|
this.element.setEleName(elementNameTextField.getText());
|
|
this.element.setEleName(elementNameTextField.getText());
|
|
});
|
|
});
|
|
@@ -326,9 +362,9 @@ public class InspectorTable extends JPanel {
|
|
cellsInRow[3] = elementNameTextField;
|
|
cellsInRow[3] = elementNameTextField;
|
|
// Energy
|
|
// Energy
|
|
|
|
|
|
- JFormattedTextField energyTextField = new JFormattedTextField(doubleFormatter);
|
|
|
|
|
|
+ energyTextField = new JFormattedTextField(doubleFormatter);
|
|
energyTextField.setInputVerifier(getInputVerifier());
|
|
energyTextField.setInputVerifier(getInputVerifier());
|
|
- energyTextField.setValue(this.element.getEnergy());
|
|
|
|
|
|
+
|
|
energyTextField.setBackground(Color.white);
|
|
energyTextField.setBackground(Color.white);
|
|
energyTextField.addPropertyChangeListener(actionEvent -> {
|
|
energyTextField.addPropertyChangeListener(actionEvent -> {
|
|
try {
|
|
try {
|
|
@@ -345,8 +381,7 @@ public class InspectorTable extends JPanel {
|
|
cellsInRow[4] = energyTextField;
|
|
cellsInRow[4] = energyTextField;
|
|
|
|
|
|
// Priority
|
|
// Priority
|
|
- JComboBox<Priority> comboBox = new JComboBox<Priority>(Priority.values());
|
|
|
|
- comboBox.setSelectedItem(this.element.getPriority());
|
|
|
|
|
|
+ comboBox = new JComboBox<Priority>(Priority.values());
|
|
comboBox.setBackground(Color.white);
|
|
comboBox.setBackground(Color.white);
|
|
comboBox.setEditable(false);
|
|
comboBox.setEditable(false);
|
|
comboBox.addActionListener(ae -> {
|
|
comboBox.addActionListener(ae -> {
|
|
@@ -360,15 +395,14 @@ public class InspectorTable extends JPanel {
|
|
checkBoxWrapperPanel.setMinimumSize(new Dimension(columnHeight, columnHeight));
|
|
checkBoxWrapperPanel.setMinimumSize(new Dimension(columnHeight, columnHeight));
|
|
checkBoxWrapperPanel.setMaximumSize(new Dimension(columnHeight, columnHeight));
|
|
checkBoxWrapperPanel.setMaximumSize(new Dimension(columnHeight, columnHeight));
|
|
// Active
|
|
// Active
|
|
- JCheckBox checkbox = new JCheckBox();
|
|
|
|
- checkbox.setSelected(this.element.isActive());
|
|
|
|
- checkbox.setBorder(BorderFactory.createEmptyBorder(0, 2, 0, 0));
|
|
|
|
- checkbox.setOpaque(false);
|
|
|
|
- checkbox.addActionListener(actionEvent -> {
|
|
|
|
- this.element.setActive(checkbox.isSelected());
|
|
|
|
|
|
+ activeCheckBox = new JCheckBox();
|
|
|
|
+ activeCheckBox.setBorder(BorderFactory.createEmptyBorder(0, 2, 0, 0));
|
|
|
|
+ activeCheckBox.setOpaque(false);
|
|
|
|
+ activeCheckBox.addActionListener(actionEvent -> {
|
|
|
|
+ this.element.setActive(activeCheckBox.isSelected());
|
|
control.calculateStateAndVisualForCurrentTimeStep();
|
|
control.calculateStateAndVisualForCurrentTimeStep();
|
|
});
|
|
});
|
|
- checkBoxWrapperPanel.add(checkbox, BorderLayout.CENTER);
|
|
|
|
|
|
+ checkBoxWrapperPanel.add(activeCheckBox, BorderLayout.CENTER);
|
|
cellsInRow[6] = checkBoxWrapperPanel;
|
|
cellsInRow[6] = checkBoxWrapperPanel;
|
|
}
|
|
}
|
|
|
|
|