mirror of
https://github.com/hneemann/Digital.git
synced 2025-09-23 04:11:54 -04:00
adds a first gui integration, see #645
This commit is contained in:
parent
e1f5d4da4c
commit
3362c09b62
@ -63,6 +63,8 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.DocumentEvent;
|
||||
import javax.swing.event.DocumentListener;
|
||||
import javax.swing.filechooser.FileNameExtensionFilter;
|
||||
import javax.swing.text.DefaultEditorKit;
|
||||
import java.awt.*;
|
||||
@ -391,7 +393,7 @@ public final class Main extends JFrame implements ClosingWindowListener.ConfirmS
|
||||
if (treeCheckBox.isSelected()) {
|
||||
JSplitPane split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
|
||||
treeModel = new LibraryTreeModel(library);
|
||||
split.setLeftComponent(new JScrollPane(new SelectTree(treeModel, circuitComponent, shapeFactory, insertHistory)));
|
||||
split.setLeftComponent(createTreeComponent());
|
||||
split.setRightComponent(circuitScrollPanel);
|
||||
getContentPane().add(split);
|
||||
componentOnPane = split;
|
||||
@ -450,6 +452,48 @@ public final class Main extends JFrame implements ClosingWindowListener.ConfirmS
|
||||
view.add(viewHelp.createJMenuItem());
|
||||
}
|
||||
|
||||
private JComponent createTreeComponent() {
|
||||
JPanel panel = new JPanel(new BorderLayout());
|
||||
JPanel field = new JPanel(new BorderLayout());
|
||||
JTextField textField = new SearchTextField();
|
||||
field.add(textField);
|
||||
JButton clearButton = new JButton(new AbstractAction("\u2717") {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent actionEvent) {
|
||||
textField.setText("");
|
||||
}
|
||||
});
|
||||
clearButton.setBorder(BorderFactory.createEmptyBorder(2, 5, 2, 5));
|
||||
field.add(clearButton, BorderLayout.EAST);
|
||||
panel.add(field, BorderLayout.NORTH);
|
||||
|
||||
textField.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
|
||||
SelectTree tree = new SelectTree(treeModel, circuitComponent, shapeFactory, insertHistory);
|
||||
textField.getDocument().addDocumentListener(new DocumentListener() {
|
||||
@Override
|
||||
public void insertUpdate(DocumentEvent documentEvent) {
|
||||
changedUpdate(documentEvent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeUpdate(DocumentEvent documentEvent) {
|
||||
changedUpdate(documentEvent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changedUpdate(DocumentEvent documentEvent) {
|
||||
String text = textField.getText().trim();
|
||||
if (text.isEmpty())
|
||||
treeModel = new LibraryTreeModel(library);
|
||||
else
|
||||
treeModel = new LibraryTreeModel(library, new TextSearchFilter(text));
|
||||
tree.setModel(treeModel);
|
||||
}
|
||||
});
|
||||
panel.add(new JScrollPane(tree));
|
||||
return panel;
|
||||
}
|
||||
|
||||
private void clearPane() {
|
||||
circuitComponent.setCircuit(new Circuit());
|
||||
setFilename(null, true);
|
||||
|
45
src/main/java/de/neemann/digital/gui/SearchTextField.java
Normal file
45
src/main/java/de/neemann/digital/gui/SearchTextField.java
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Helmut Neemann.
|
||||
* Use of this source code is governed by the GPL v3 license
|
||||
* that can be found in the LICENSE file.
|
||||
*/
|
||||
package de.neemann.digital.gui;
|
||||
|
||||
import de.neemann.digital.lang.Lang;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.FocusEvent;
|
||||
import java.awt.event.FocusListener;
|
||||
|
||||
/**
|
||||
* JTextField which shows the text "search" if the field is empty.
|
||||
*/
|
||||
public class SearchTextField extends JTextField {
|
||||
|
||||
/**
|
||||
* Creates a new instance
|
||||
*/
|
||||
public SearchTextField() {
|
||||
addFocusListener(new FocusListener() {
|
||||
@Override
|
||||
public void focusGained(FocusEvent e) {
|
||||
repaint();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void focusLost(FocusEvent e) {
|
||||
repaint();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint(Graphics g) {
|
||||
super.paint(g);
|
||||
if (getText().isEmpty() && !hasFocus()) {
|
||||
g.setColor(Color.GRAY);
|
||||
g.drawString(Lang.get("msg_search"), 5, (getHeight() + getFont().getSize()) / 2);
|
||||
}
|
||||
}
|
||||
}
|
31
src/main/java/de/neemann/digital/gui/TextSearchFilter.java
Normal file
31
src/main/java/de/neemann/digital/gui/TextSearchFilter.java
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Helmut Neemann.
|
||||
* Use of this source code is governed by the GPL v3 license
|
||||
* that can be found in the LICENSE file.
|
||||
*/
|
||||
package de.neemann.digital.gui;
|
||||
|
||||
import de.neemann.digital.draw.library.LibraryNode;
|
||||
import de.neemann.digital.gui.components.tree.LibraryTreeModel;
|
||||
|
||||
/**
|
||||
* Used to filter nodes in the tree view
|
||||
*/
|
||||
public class TextSearchFilter implements LibraryTreeModel.Filter {
|
||||
private final String filterStr;
|
||||
|
||||
/**
|
||||
* Creates a new filter
|
||||
*
|
||||
* @param filterStr the search string
|
||||
*/
|
||||
public TextSearchFilter(String filterStr) {
|
||||
this.filterStr = filterStr.toLowerCase();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(LibraryNode node) {
|
||||
return node.getName().toLowerCase().contains(filterStr)
|
||||
|| node.getTranslatedName().toLowerCase().contains(filterStr);
|
||||
}
|
||||
}
|
@ -111,6 +111,13 @@ public class LibraryTreeModel implements TreeModel, LibraryListener {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if this model is filtered
|
||||
*/
|
||||
public boolean isFiltered() {
|
||||
return filter != null;
|
||||
}
|
||||
|
||||
private Container getContainer(LibraryNode libraryNode) {
|
||||
Container c = map.get(libraryNode);
|
||||
if (c == null) {
|
||||
|
@ -22,6 +22,7 @@ import java.awt.*;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.io.IOException;
|
||||
import java.util.Enumeration;
|
||||
|
||||
/**
|
||||
* Tree to select items
|
||||
@ -29,6 +30,7 @@ import java.io.IOException;
|
||||
public class SelectTree extends JTree {
|
||||
|
||||
private final ShapeFactory shapeFactory;
|
||||
private Enumeration<TreePath> storedExpanded;
|
||||
|
||||
/**
|
||||
* Create a new instance
|
||||
@ -68,6 +70,27 @@ public class SelectTree extends JTree {
|
||||
expandPath(new TreePath(model.getFirstLeafParent().getPath()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a new model to this SelectTree.
|
||||
*
|
||||
* @param newModel the new model
|
||||
*/
|
||||
public void setModel(LibraryTreeModel newModel) {
|
||||
LibraryTreeModel oldModel = (LibraryTreeModel) getModel();
|
||||
if (!oldModel.isFiltered() && newModel.isFiltered())
|
||||
storedExpanded = getExpandedDescendants(new TreePath(getModel().getRoot()));
|
||||
|
||||
boolean restore = oldModel.isFiltered() && !newModel.isFiltered();
|
||||
|
||||
super.setModel(newModel);
|
||||
if (restore && storedExpanded != null) {
|
||||
while (storedExpanded.hasMoreElements())
|
||||
expandPath(storedExpanded.nextElement());
|
||||
storedExpanded = null;
|
||||
} else
|
||||
expandPath(new TreePath(newModel.getFirstLeafParent().getPath()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getToolTipText(MouseEvent e) {
|
||||
TreePath selPath = getPathForLocation(e.getX(), e.getY());
|
||||
|
@ -51,7 +51,7 @@
|
||||
<string name="elem_Help_inputs">Eingänge</string>
|
||||
<string name="elem_Help_outputs">Ausgänge</string>
|
||||
<string name="elem_Help_attributes">Veränderbare Attribute</string>
|
||||
|
||||
<string name="msg_search">Suche</string>
|
||||
|
||||
<!-- logik -->
|
||||
|
||||
|
@ -51,6 +51,7 @@
|
||||
<string name="elem_Help_inputs">Inputs</string>
|
||||
<string name="elem_Help_outputs">Outputs</string>
|
||||
<string name="elem_Help_attributes">Attributes</string>
|
||||
<string name="msg_search">search</string>
|
||||
|
||||
|
||||
<!-- logic -->
|
||||
|
Loading…
x
Reference in New Issue
Block a user