diff options
Diffstat (limited to 'src/org/unitConverter/converterGUI')
-rw-r--r-- | src/org/unitConverter/converterGUI/SearchBoxList.java | 122 | ||||
-rw-r--r-- | src/org/unitConverter/converterGUI/UnitConverterGUI.java | 89 |
2 files changed, 141 insertions, 70 deletions
diff --git a/src/org/unitConverter/converterGUI/SearchBoxList.java b/src/org/unitConverter/converterGUI/SearchBoxList.java index 1995466..10ef589 100644 --- a/src/org/unitConverter/converterGUI/SearchBoxList.java +++ b/src/org/unitConverter/converterGUI/SearchBoxList.java @@ -36,13 +36,13 @@ import javax.swing.JTextField; * @since v0.2.0 */ final class SearchBoxList extends JPanel { - + /** * @since 2019-04-13 * @since v0.2.0 */ private static final long serialVersionUID = 6226930279415983433L; - + /** * The text to place in an empty search box. * @@ -50,7 +50,7 @@ final class SearchBoxList extends JPanel { * @since v0.2.0 */ private static final String EMPTY_TEXT = "Search..."; - + /** * The color to use for an empty foreground. * @@ -58,94 +58,92 @@ final class SearchBoxList extends JPanel { * @since v0.2.0 */ private static final Color EMPTY_FOREGROUND = new Color(192, 192, 192); - + // the components private final Collection<String> itemsToFilter; private final DelegateListModel<String> listModel; private final JTextField searchBox; private final JList<String> searchItems; - + private boolean searchBoxEmpty = true; - - // I need to do this because, for some reason, Swing is auto-focusing my search box without triggering a focus + + // I need to do this because, for some reason, Swing is auto-focusing my + // search box without triggering a focus // event. private boolean searchBoxFocused = false; - + private Predicate<String> customSearchFilter = o -> true; private final Comparator<String> defaultOrdering; private final boolean caseSensitive; - + /** * Creates the {@code SearchBoxList}. * - * @param itemsToFilter - * items to put in the list + * @param itemsToFilter items to put in the list * @since 2019-04-14 */ public SearchBoxList(final Collection<String> itemsToFilter) { this(itemsToFilter, null, false); } - + /** * Creates the {@code SearchBoxList}. * - * @param itemsToFilter - * items to put in the list - * @param defaultOrdering - * default ordering of items after filtration (null=Comparable) - * @param caseSensitive - * whether or not the filtration is case-sensitive + * @param itemsToFilter items to put in the list + * @param defaultOrdering default ordering of items after filtration + * (null=Comparable) + * @param caseSensitive whether or not the filtration is case-sensitive * * @since 2019-04-13 * @since v0.2.0 */ - public SearchBoxList(final Collection<String> itemsToFilter, final Comparator<String> defaultOrdering, + public SearchBoxList(final Collection<String> itemsToFilter, + final Comparator<String> defaultOrdering, final boolean caseSensitive) { super(new BorderLayout(), true); this.itemsToFilter = itemsToFilter; this.defaultOrdering = defaultOrdering; this.caseSensitive = caseSensitive; - + // create the components this.listModel = new DelegateListModel<>(new ArrayList<>(itemsToFilter)); this.searchItems = new JList<>(this.listModel); - + this.searchBox = new JTextField(EMPTY_TEXT); this.searchBox.setForeground(EMPTY_FOREGROUND); - + // add them to the panel this.add(this.searchBox, BorderLayout.PAGE_START); this.add(new JScrollPane(this.searchItems), BorderLayout.CENTER); - + // set up the search box this.searchBox.addFocusListener(new FocusListener() { @Override public void focusGained(final FocusEvent e) { SearchBoxList.this.searchBoxFocusGained(e); } - + @Override public void focusLost(final FocusEvent e) { SearchBoxList.this.searchBoxFocusLost(e); } }); - + this.searchBox.addCaretListener(e -> this.searchBoxTextChanged()); this.searchBoxEmpty = true; } - + /** * Adds an additional filter for searching. * - * @param filter - * filter to add. + * @param filter filter to add. * @since 2019-04-13 * @since v0.2.0 */ public void addSearchFilter(final Predicate<String> filter) { this.customSearchFilter = this.customSearchFilter.and(filter); } - + /** * Resets the search filter. * @@ -155,7 +153,7 @@ final class SearchBoxList extends JPanel { public void clearSearchFilters() { this.customSearchFilter = o -> true; } - + /** * @return this component's search box component * @since 2019-04-14 @@ -164,11 +162,11 @@ final class SearchBoxList extends JPanel { public final JTextField getSearchBox() { return this.searchBox; } - + /** - * @param searchText - * text to search for - * @return a filter that filters out that text, based on this list's case sensitive setting + * @param searchText text to search for + * @return a filter that filters out that text, based on this list's case + * sensitive setting * @since 2019-04-14 * @since v0.2.0 */ @@ -176,9 +174,10 @@ final class SearchBoxList extends JPanel { if (this.caseSensitive) return string -> string.contains(searchText); else - return string -> string.toLowerCase().contains(searchText.toLowerCase()); + return string -> string.toLowerCase() + .contains(searchText.toLowerCase()); } - + /** * @return this component's list component * @since 2019-04-14 @@ -187,7 +186,7 @@ final class SearchBoxList extends JPanel { public final JList<String> getSearchList() { return this.searchItems; } - + /** * @return index selected in item list * @since 2019-04-14 @@ -196,7 +195,7 @@ final class SearchBoxList extends JPanel { public int getSelectedIndex() { return this.searchItems.getSelectedIndex(); } - + /** * @return value selected in item list * @since 2019-04-13 @@ -205,7 +204,7 @@ final class SearchBoxList extends JPanel { public String getSelectedValue() { return this.searchItems.getSelectedValue(); } - + /** * Re-applies the filters. * @@ -213,29 +212,30 @@ final class SearchBoxList extends JPanel { * @since v0.2.0 */ public void reapplyFilter() { - final String searchText = this.searchBoxEmpty ? "" : this.searchBox.getText(); - final FilterComparator comparator = new FilterComparator(searchText, this.defaultOrdering, this.caseSensitive); + final String searchText = this.searchBoxEmpty ? "" + : this.searchBox.getText(); + final FilterComparator comparator = new FilterComparator(searchText, + this.defaultOrdering, this.caseSensitive); final Predicate<String> searchFilter = this.getSearchFilter(searchText); - + this.listModel.clear(); this.itemsToFilter.forEach(string -> { if (searchFilter.test(string)) { this.listModel.add(string); } }); - + // applies the custom filters this.listModel.removeIf(this.customSearchFilter.negate()); - + // sorts the remaining items this.listModel.sort(comparator); } - + /** * Runs whenever the search box gains focus. * - * @param e - * focus event + * @param e focus event * @since 2019-04-13 * @since v0.2.0 */ @@ -246,12 +246,11 @@ final class SearchBoxList extends JPanel { this.searchBox.setForeground(Color.BLACK); } } - + /** * Runs whenever the search box loses focus. * - * @param e - * focus event + * @param e focus event * @since 2019-04-13 * @since v0.2.0 */ @@ -262,7 +261,7 @@ final class SearchBoxList extends JPanel { this.searchBox.setForeground(EMPTY_FOREGROUND); } } - + /** * Runs whenever the text in the search box is changed. * <p> @@ -276,10 +275,12 @@ final class SearchBoxList extends JPanel { if (this.searchBoxFocused) { this.searchBoxEmpty = this.searchBox.getText().equals(""); } - final String searchText = this.searchBoxEmpty ? "" : this.searchBox.getText(); - final FilterComparator comparator = new FilterComparator(searchText, this.defaultOrdering, this.caseSensitive); + final String searchText = this.searchBoxEmpty ? "" + : this.searchBox.getText(); + final FilterComparator comparator = new FilterComparator(searchText, + this.defaultOrdering, this.caseSensitive); final Predicate<String> searchFilter = this.getSearchFilter(searchText); - + // initialize list with items that match the filter then sort this.listModel.clear(); this.itemsToFilter.forEach(string -> { @@ -287,11 +288,20 @@ final class SearchBoxList extends JPanel { this.listModel.add(string); } }); - + // applies the custom filters this.listModel.removeIf(this.customSearchFilter.negate()); - + // sorts the remaining items this.listModel.sort(comparator); } + + /** + * Manually updates the search box's item list. + * + * @since 2020-08-27 + */ + public void updateList() { + this.searchBoxTextChanged(); + } } diff --git a/src/org/unitConverter/converterGUI/UnitConverterGUI.java b/src/org/unitConverter/converterGUI/UnitConverterGUI.java index 5fe4ee5..75ab16d 100644 --- a/src/org/unitConverter/converterGUI/UnitConverterGUI.java +++ b/src/org/unitConverter/converterGUI/UnitConverterGUI.java @@ -56,6 +56,7 @@ import javax.swing.JTextField; import javax.swing.WindowConstants; import javax.swing.border.TitledBorder; +import org.unitConverter.math.ConditionalExistenceCollections; import org.unitConverter.math.ObjectProduct; import org.unitConverter.unit.BaseDimension; import org.unitConverter.unit.BritishImperial; @@ -129,6 +130,13 @@ final class UnitConverterGUI { private final Comparator<String> prefixNameComparator; + // conditions for existence of From and To entries + // used for one-way conversion + private final MutablePredicate<String> fromExistenceCondition = new MutablePredicate<>( + s -> true); + private final MutablePredicate<String> toExistenceCondition = new MutablePredicate<>( + s -> true); + /* * Rounding-related settings. I am using my own system, and not * MathContext, because MathContext does not support decimal place based @@ -338,6 +346,16 @@ final class UnitConverterGUI { } /** + * @return a list of all the entries in the dimension-based converter's + * From box + * @since 2020-08-27 + */ + public final Set<String> fromEntries() { + return ConditionalExistenceCollections.conditionalExistenceSet( + this.unitNameSet(), this.fromExistenceCondition); + } + + /** * @return a comparator to compare prefix names * @since 2019-04-14 * @since v0.2.0 @@ -437,6 +455,25 @@ final class UnitConverterGUI { } /** + * Enables or disables one-way conversion. + * + * @param oneWay whether one-way conversion should be on (true) or off + * (false) + * @since 2020-08-27 + */ + public final void setOneWay(boolean oneWay) { + if (oneWay) { + this.fromExistenceCondition.setPredicate( + unitName -> !this.database.getUnit(unitName).isMetric()); + this.toExistenceCondition.setPredicate( + unitName -> this.database.getUnit(unitName).isMetric()); + } else { + this.fromExistenceCondition.setPredicate(unitName -> true); + this.toExistenceCondition.setPredicate(unitName -> true); + } + } + + /** * @param precision new value of precision * @since 2019-01-15 * @since v0.1.0 @@ -463,6 +500,16 @@ final class UnitConverterGUI { } /** + * @return a list of all the entries in the dimension-based converter's To + * box + * @since 2020-08-27 + */ + public final Set<String> toEntries() { + return ConditionalExistenceCollections.conditionalExistenceSet( + this.unitNameSet(), this.toExistenceCondition); + } + + /** * Returns true if and only if the unit represented by {@code unitName} * has the dimension represented by {@code dimensionName}. * @@ -505,7 +552,7 @@ final class UnitConverterGUI { * @since 2019-04-14 * @since v0.2.0 */ - public final Set<String> unitNameSet() { + private final Set<String> unitNameSet() { return this.database.unitMapPrefixless().keySet(); } } @@ -579,8 +626,8 @@ final class UnitConverterGUI { this.presenter.getPrefixNameComparator(), true); this.unitTextBox = new JTextArea(); this.prefixTextBox = new JTextArea(); - this.fromSearch = new SearchBoxList(this.presenter.unitNameSet()); - this.toSearch = new SearchBoxList(this.presenter.unitNameSet()); + this.fromSearch = new SearchBoxList(this.presenter.fromEntries()); + this.toSearch = new SearchBoxList(this.presenter.toEntries()); this.valueInput = new JFormattedTextField(NUMBER_FORMATTER); this.dimensionBasedOutput = new JTextArea(2, 32); this.fromEntry = new JTextField(); @@ -630,15 +677,6 @@ final class UnitConverterGUI { } /** - * @return text inputted into dimension-based converter - * @since 2019-04-13 - * @since v0.2.0 - */ - public String getDimensionConverterText() { - return this.valueInput.getText(); - } - - /** * @return selection in "From" selector in dimension-based converter * @since 2019-04-13 * @since v0.2.0 @@ -717,6 +755,9 @@ final class UnitConverterGUI { { // pane with all of the tabs masterPanel.add(this.masterPane, BorderLayout.CENTER); + // update stuff + this.masterPane.addChangeListener(e -> this.update()); + { // a panel for unit conversion using a selector final JPanel convertUnitPanel = new JPanel(); this.masterPane.addTab("Convert Units", convertUnitPanel); @@ -1080,17 +1121,25 @@ final class UnitConverterGUI { .setBorder(new TitledBorder("Miscellaneous Settings")); miscPanel.setLayout(new GridBagLayout()); + final JCheckBox oneWay = new JCheckBox( + "Convert One Way Only"); + oneWay.setSelected(false); + oneWay.addItemListener( + e -> this.presenter.setOneWay(e.getStateChange() == 1)); + miscPanel.add(oneWay, new GridBagBuilder(0, 0) + .setAnchor(GridBagConstraints.LINE_START).build()); + final JCheckBox showAllVariations = new JCheckBox( "Show Symbols in \"Convert Units\""); showAllVariations.setSelected(true); showAllVariations.setEnabled(false); - miscPanel.add(showAllVariations, new GridBagBuilder(0, 0) + miscPanel.add(showAllVariations, new GridBagBuilder(0, 1) .setAnchor(GridBagConstraints.LINE_START).build()); final JButton unitFileButton = new JButton( "Manage Unit Data Files"); unitFileButton.setEnabled(false); - miscPanel.add(unitFileButton, new GridBagBuilder(0, 1) + miscPanel.add(unitFileButton, new GridBagBuilder(0, 2) .setAnchor(GridBagConstraints.LINE_START).build()); } } @@ -1153,6 +1202,18 @@ final class UnitConverterGUI { JOptionPane.showMessageDialog(this.frame, message, title, JOptionPane.ERROR_MESSAGE); } + + public void update() { + switch (this.getActivePane()) { + case UNIT_CONVERTER: + this.fromSearch.updateList(); + this.toSearch.updateList(); + break; + default: + // do nothing, for now + break; + } + } } public static void main(final String[] args) { |