updated translations, added java doc comments
This commit is contained in:
2
pom.xml
2
pom.xml
@@ -4,7 +4,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>BelegScanner</groupId>
|
||||
<artifactId>BelegScanner</artifactId>
|
||||
<version>1.0.2</version>
|
||||
<version>1.0.3</version>
|
||||
|
||||
<name>BelegScanner</name>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
@@ -1,11 +1,30 @@
|
||||
Actions : Aktionen
|
||||
Category : Kategorie
|
||||
CATEGORY : KATEGORIE
|
||||
Conversion failed. : Konvertierung fehlgeschlagen.
|
||||
Converting to PDF… : Kovertiere zu PDF…
|
||||
current resolution : aktuelle Auflösung
|
||||
DAY : TAG
|
||||
height : Höhe
|
||||
Directory : Ordner
|
||||
display preview : Vorschau anzeigen
|
||||
done : fertig
|
||||
Error code\: {} for {} : Fehlercode: {} für {}
|
||||
Finished text recognition. : Texterkennung beendet.
|
||||
Height : Höhe
|
||||
Joining PDFs… : Verbinde PDFs…
|
||||
join PDFs : PDFs zusammenführen
|
||||
MONTH : MONAT
|
||||
OCR failed. : OCR fehlgeschlagen.
|
||||
open folder : Ordner öffnen
|
||||
Path '{}' does not exist! : Pfad '{}' existiert nicht!
|
||||
Path : Pfad
|
||||
PDFs joined. : Zusammengefügt.:
|
||||
Press Shift + Delete to remove an entry. : Drücken Sie Umschalt + Entf um einen Eintrag zu löschen
|
||||
scanning… : Scanne…
|
||||
width : Breite
|
||||
Scan failed. : Scannen fehlgeschlagen.
|
||||
Scanning… : Scanne…
|
||||
scan! : scannen!
|
||||
State : Status
|
||||
{} terminated\: : {} abgebrochen:
|
||||
Text recognition… : Texterkennung…
|
||||
Width : Breite
|
||||
YEAR : JAHR
|
||||
|
||||
12
resources/translations/DateChooser.de.translation
Normal file
12
resources/translations/DateChooser.de.translation
Normal file
@@ -0,0 +1,12 @@
|
||||
December : Dezember
|
||||
February : Februar
|
||||
January : Januar
|
||||
July : Juli
|
||||
June : Juni
|
||||
March : März
|
||||
May : Mai
|
||||
October : Oktober
|
||||
Su : So
|
||||
Th : Do
|
||||
Tu : Di
|
||||
We : Mi
|
||||
@@ -5,6 +5,12 @@ import java.io.IOException;
|
||||
import de.srsoftware.belegscanner.gui.MainFrame;
|
||||
import de.srsoftware.tools.translations.Translation;
|
||||
|
||||
/**
|
||||
* Application to scan receipts : entry point
|
||||
*
|
||||
* @author Stephan Richter <s.richter@srsoftware.de>
|
||||
*
|
||||
*/
|
||||
public class Application {
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
@@ -13,6 +19,12 @@ public class Application {
|
||||
app.setDefaultCloseOperation(MainFrame.EXIT_ON_CLOSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate a text.
|
||||
* @param txt the text to be translated.
|
||||
* @param fills Replacements for occurrences of the place holders ('{}').
|
||||
* @return
|
||||
*/
|
||||
public static String t(String txt, Object...fills) {
|
||||
return Translation.get(Application.class, txt, fills);
|
||||
}
|
||||
|
||||
@@ -13,12 +13,24 @@ import org.json.JSONObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
*
|
||||
* JSON-based Configuration manager for the Application.
|
||||
*
|
||||
* @author Stephan Richter <s.richter@srsoftware.de>
|
||||
*
|
||||
*/
|
||||
public class Configuration {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(Configuration.class);
|
||||
private File file;
|
||||
private JSONObject json = new JSONObject();
|
||||
|
||||
/**
|
||||
* Create/Load configuration for the application.
|
||||
* @param appName
|
||||
* @throws IOException
|
||||
*/
|
||||
public Configuration(String appName) throws IOException {
|
||||
String home = System.getProperty("user.home");
|
||||
String fileName = new StringBuilder().append(home).append(File.separator).append(".config").append(File.separator).append(appName).append(File.separator).append("config.json").toString();
|
||||
@@ -40,6 +52,10 @@ public class Configuration {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write contents of the configuration object to the underlying file.
|
||||
* @throws IOException
|
||||
*/
|
||||
public void save() throws IOException {
|
||||
LOG.debug("Trying to save config…");
|
||||
File dir = file.getParentFile();
|
||||
@@ -49,6 +65,11 @@ public class Configuration {
|
||||
out.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Load an JSON array from the configuration
|
||||
* @param key Search path in the form path.to.array
|
||||
* @return
|
||||
*/
|
||||
public JSONArray getOrCreateArray(String key) {
|
||||
LOG.debug("requesting {} from config.",key);
|
||||
String[] parts = key.split("\\.");
|
||||
@@ -76,6 +97,12 @@ public class Configuration {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load an Object from the configuration
|
||||
* @param <T>
|
||||
* @param key Search path in the form path.to.array
|
||||
* @return null, if no such path is found
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T get(String key) {
|
||||
LOG.debug("requesting {} from config.",key);
|
||||
@@ -92,6 +119,13 @@ public class Configuration {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load an Object from the configuration, create it, if it is not present
|
||||
* @param <T>
|
||||
* @param key Search path in the form path.to.array
|
||||
* @param preset Content for the path, if it does not exist
|
||||
* @return preset, if no such path is found
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T getOrCreate(String key, T preset) {
|
||||
LOG.debug("requesting {} from config.",key);
|
||||
@@ -120,6 +154,11 @@ public class Configuration {
|
||||
return (T) result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new value to the configuration or replace an existing value
|
||||
* @param key Search path in the form path.to.array
|
||||
* @param value the value to add/replace
|
||||
*/
|
||||
public void set(String key, Object value) {
|
||||
LOG.debug("setting {} to {}",key,value);
|
||||
String[] parts = key.split("\\.");
|
||||
|
||||
@@ -31,6 +31,12 @@ import org.slf4j.LoggerFactory;
|
||||
import de.srsoftware.belegscanner.Constants;
|
||||
import static de.srsoftware.belegscanner.Application.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* Creates a table of previously scanned documents.
|
||||
* @author Stephan Richter <s.richter@srsoftware.de>
|
||||
*
|
||||
*/
|
||||
public class DocTable extends JPanel{
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(DocTable.class);
|
||||
@@ -43,6 +49,11 @@ public class DocTable extends JPanel{
|
||||
public void show(String filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* represents on previously scanned document
|
||||
* @author Stephan Richter <s.richter@srsoftware.de>
|
||||
*
|
||||
*/
|
||||
private class Row{
|
||||
|
||||
private JLabel status;
|
||||
@@ -74,6 +85,10 @@ public class DocTable extends JPanel{
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* drop the selected document from the table
|
||||
* @param row
|
||||
*/
|
||||
private void drop(Row row) {
|
||||
remove(pathLabel);
|
||||
remove(status);
|
||||
@@ -83,11 +98,19 @@ public class DocTable extends JPanel{
|
||||
rows.remove(path);
|
||||
}
|
||||
|
||||
/**
|
||||
* update status for selected document
|
||||
* @param status
|
||||
* @return
|
||||
*/
|
||||
public Row status(String status) {
|
||||
this.status.setText(status);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* remove the join button assigned with the selected document
|
||||
*/
|
||||
public void removeJoinButton() {
|
||||
buttons.remove(joinButton);
|
||||
}
|
||||
@@ -100,6 +123,9 @@ public class DocTable extends JPanel{
|
||||
private HashSet<PreviewListener> previewListeners;
|
||||
private GridBagConstraints constraints;
|
||||
|
||||
/**
|
||||
* create a new DocTable
|
||||
*/
|
||||
public DocTable() {
|
||||
setLayout(new GridBagLayout());
|
||||
constraints = new GridBagConstraints();
|
||||
@@ -122,15 +148,31 @@ public class DocTable extends JPanel{
|
||||
previewListeners = new HashSet<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Ad a table entry for the directory represented by path
|
||||
* @param path
|
||||
*/
|
||||
public void add(String path) {
|
||||
if (!rows.containsKey(path)) new Row(path).status("neu");
|
||||
}
|
||||
|
||||
/**
|
||||
* register a listener for changes of the preview area
|
||||
* @param listener
|
||||
* @return
|
||||
*/
|
||||
public DocTable addPreviewListener(PreviewListener listener) {
|
||||
previewListeners.add(listener);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* helper method to create a button with given label, tooltip and action listener
|
||||
* @param label
|
||||
* @param tooltip
|
||||
* @param listener
|
||||
* @return
|
||||
*/
|
||||
private static JButton button(String label, String tooltip, ActionListener listener) {
|
||||
JButton btn = new JButton(label);
|
||||
btn.setFont(btnFont);
|
||||
@@ -139,6 +181,10 @@ public class DocTable extends JPanel{
|
||||
return btn;
|
||||
}
|
||||
|
||||
/**
|
||||
* join documents in given path
|
||||
* @param path
|
||||
*/
|
||||
public void joinDocs(String path) {
|
||||
LOG.debug("joinFiles({})",path);
|
||||
rows.get(path).removeJoinButton();
|
||||
@@ -172,6 +218,10 @@ public class DocTable extends JPanel{
|
||||
preview(path);
|
||||
}
|
||||
|
||||
/**
|
||||
* open given path in external file browser
|
||||
* @param path
|
||||
*/
|
||||
public void openFolder(String path) {
|
||||
Process process = null;
|
||||
try {
|
||||
@@ -189,6 +239,10 @@ public class DocTable extends JPanel{
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* show lates document of the given directory in preview area
|
||||
* @param path
|
||||
*/
|
||||
public void preview(String path) {
|
||||
LOG.debug("preview({})",path);
|
||||
File folder = new File(path);
|
||||
@@ -198,6 +252,11 @@ public class DocTable extends JPanel{
|
||||
if (!pdfs.isEmpty()) previewListeners.forEach(l -> l.show(Path.of(path,pdfs.get(0)).toString()));
|
||||
}
|
||||
|
||||
/**
|
||||
* update state column text for given path
|
||||
* @param path
|
||||
* @param state
|
||||
*/
|
||||
public void setState(String path, String state) {
|
||||
Row row = rows.get(path);
|
||||
if (row != null) row.status(state);
|
||||
|
||||
@@ -1,112 +0,0 @@
|
||||
package de.srsoftware.belegscanner.gui;
|
||||
|
||||
import java.awt.EventQueue;
|
||||
import java.awt.event.ItemEvent;
|
||||
import java.awt.event.ItemListener;
|
||||
import java.awt.event.KeyAdapter;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.DefaultComboBoxModel;
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
public class FilterComboBoxText {
|
||||
|
||||
private JFrame frame;
|
||||
private final JComboBox<String> comboBox = new JComboBox<>();
|
||||
private static List<String>listForComboBox= new ArrayList<String>();
|
||||
|
||||
/**
|
||||
* Launch the application.
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
EventQueue.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
FilterComboBoxText window = new FilterComboBoxText();
|
||||
window.frame.setVisible(true);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
listForComboBox.add("Lion");
|
||||
listForComboBox.add("LionKing");
|
||||
listForComboBox.add("Mufasa");
|
||||
listForComboBox.add("Nala");
|
||||
listForComboBox.add("KingNala");
|
||||
listForComboBox.add("Animals");
|
||||
listForComboBox.add("Anims");
|
||||
listForComboBox.add("Fish");
|
||||
listForComboBox.add("Jelly Fish");
|
||||
listForComboBox.add("I am the boss");
|
||||
|
||||
|
||||
}
|
||||
|
||||
public FilterComboBoxText() {
|
||||
initialize();
|
||||
}
|
||||
|
||||
private void initialize() {
|
||||
frame = new JFrame();
|
||||
frame.setBounds(100, 100, 412, 165);
|
||||
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
frame.getContentPane().setLayout(null);
|
||||
comboBox.setEditable(true);
|
||||
|
||||
comboBox.addItemListener(new ItemListener() {
|
||||
public void itemStateChanged(ItemEvent arg0) {
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
for(String detail : listForComboBox) comboBox.addItem(detail);
|
||||
final JTextField textfield = (JTextField) comboBox.getEditor().getEditorComponent();
|
||||
textfield.addKeyListener(new KeyAdapter() {
|
||||
public void keyReleased(KeyEvent ke) {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
if(!textfield.getText().isEmpty()){
|
||||
comboBoxFilter(textfield.getText());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
});
|
||||
comboBox.setBounds(10, 39, 364, 29);
|
||||
frame.getContentPane().add(comboBox);
|
||||
}
|
||||
|
||||
public void comboBoxFilter(String enteredText) {
|
||||
System.out.println(comboBox.getItemCount());
|
||||
|
||||
if (!comboBox.isPopupVisible()) {
|
||||
comboBox.showPopup();
|
||||
}
|
||||
|
||||
List<String> filterArray= new ArrayList<String>();
|
||||
for (int i = 0; i < listForComboBox.size(); i++) {
|
||||
if (listForComboBox.get(i).toLowerCase().contains(enteredText.toLowerCase())) {
|
||||
filterArray.add(listForComboBox.get(i));
|
||||
}
|
||||
}
|
||||
if (filterArray.size() > 0) {
|
||||
DefaultComboBoxModel<String> model = (DefaultComboBoxModel<String>) comboBox.getModel();
|
||||
model.removeAllElements();
|
||||
model.addElement("");
|
||||
for (String s: filterArray)
|
||||
model.addElement(s);
|
||||
|
||||
JTextField textfield = (JTextField) comboBox.getEditor().getEditorComponent();
|
||||
textfield.setText(enteredText);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -34,6 +34,12 @@ import static de.srsoftware.belegscanner.Application.*;
|
||||
import de.srsoftware.belegscanner.Configuration;
|
||||
|
||||
|
||||
/**
|
||||
* The "guts" of the application:
|
||||
* Combines all panels and provides execution logic.
|
||||
* @author Stephan Richter <s.richter@srsoftware.de>
|
||||
*
|
||||
*/
|
||||
public class MainFrame extends JFrame {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(MainFrame.class);
|
||||
|
||||
@@ -77,6 +83,10 @@ public class MainFrame extends JFrame {
|
||||
|
||||
private boolean isScanning = false;
|
||||
|
||||
/**
|
||||
* Create application main frame.
|
||||
* @param config
|
||||
*/
|
||||
public MainFrame(Configuration config) {
|
||||
super("BelegScanner");
|
||||
this.config = config;
|
||||
@@ -116,6 +126,10 @@ public class MainFrame extends JFrame {
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Scans the given path for occurences of '$VARIABLES' and creates input fields for the found variables.
|
||||
* @param path
|
||||
*/
|
||||
private void addFieldsFor(String path) {
|
||||
Vector<String> marks = new Vector<>();
|
||||
Matcher matches = MARKEN.matcher(path);
|
||||
@@ -123,10 +137,18 @@ public class MainFrame extends JFrame {
|
||||
toolbar.addFieldsFor(marks);
|
||||
};
|
||||
|
||||
/**
|
||||
* checks, whether the scan button may be enabled.
|
||||
*/
|
||||
private void checkScanButton() {
|
||||
toolbar.readyToScan(!(isScanning || patchedPath==null || patchedPath.isBlank() || patchedPath.contains("$")));
|
||||
}
|
||||
|
||||
/**
|
||||
* scan a new document, convert it to pdf and perform text recognition
|
||||
* @param path
|
||||
* @param dimension
|
||||
*/
|
||||
private void performScan(String path, Dimension dimension) {
|
||||
LOG.debug("performScan({})",path);
|
||||
setScanning(true);
|
||||
@@ -233,6 +255,10 @@ public class MainFrame extends JFrame {
|
||||
docTable.preview(path);
|
||||
}
|
||||
|
||||
/**
|
||||
* create preview panel
|
||||
* @return
|
||||
*/
|
||||
private JPanel preview() {
|
||||
// https://stackoverflow.com/a/48248739/1285585
|
||||
JPanel pane = new JPanel(new BorderLayout());
|
||||
@@ -255,6 +281,10 @@ public class MainFrame extends JFrame {
|
||||
return pane;
|
||||
}
|
||||
|
||||
/**
|
||||
* open file in preview panel
|
||||
* @param file
|
||||
*/
|
||||
private void preview(String file) {
|
||||
pdfViewer.openDocument(file);
|
||||
//pdfViewer.setToolBarVisible(false);
|
||||
@@ -262,27 +292,48 @@ public class MainFrame extends JFrame {
|
||||
fileName.setText(file);
|
||||
}
|
||||
|
||||
/**
|
||||
* save config, then start scannin in separate thread
|
||||
* @param ev
|
||||
*/
|
||||
private void scan(ActionEvent ev) {
|
||||
updateConfig();
|
||||
new Thread(() -> performScan(patchedPath,dimension)).start();
|
||||
}
|
||||
|
||||
/**
|
||||
* update the category currently used
|
||||
* @param category
|
||||
*/
|
||||
private void setCategory(String category) {
|
||||
this.category = category;
|
||||
updatePath();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* update the date currently used
|
||||
* @param date
|
||||
*/
|
||||
private void setDate(Date date) {
|
||||
this.date = date;
|
||||
updatePath();
|
||||
}
|
||||
|
||||
/**
|
||||
* update the scan dimensions currently used
|
||||
* @param dim
|
||||
*/
|
||||
private void setDimension(Dimension dim) {
|
||||
this.dimension = dim;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* update the value of a variable field
|
||||
* @param key
|
||||
* @param val
|
||||
*/
|
||||
private void setField(String key, String val) {
|
||||
if (val == null || val.isEmpty()) {
|
||||
fields.remove(key);
|
||||
@@ -291,18 +342,29 @@ public class MainFrame extends JFrame {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* update the path currently used as scan target directory
|
||||
* @param path
|
||||
*/
|
||||
private void setPath(String path) {
|
||||
this.path = path;
|
||||
updatePath();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* toggle scanning state
|
||||
* @param scanning
|
||||
*/
|
||||
private void setScanning(boolean scanning) {
|
||||
isScanning = scanning;
|
||||
checkScanButton();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* push current settings to the configuration, then save it.
|
||||
*/
|
||||
private void updateConfig() {
|
||||
|
||||
String prefix = "app.categories."+category+".";
|
||||
@@ -332,6 +394,9 @@ public class MainFrame extends JFrame {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* compile path, variable values, date to a patched path
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
private void updatePath() {
|
||||
LOG.debug("updatePath() [path = {}]",path);
|
||||
|
||||
@@ -8,6 +8,12 @@ import javax.swing.border.EmptyBorder;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Simple status barwith updateable text.
|
||||
* This class may be extended to show more status information.
|
||||
* @author Stephan Richter <s.richter@srsoftware.de>
|
||||
*
|
||||
*/
|
||||
public class StatusBar extends JPanel {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(StatusBar.class);
|
||||
@@ -15,8 +21,6 @@ public class StatusBar extends JPanel {
|
||||
private static final long serialVersionUID = 8102800846089594705L;
|
||||
private JLabel path;
|
||||
|
||||
//private JLabel action;
|
||||
|
||||
public StatusBar() {
|
||||
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
|
||||
add(path = new JLabel("Kein Pfad gewält."));
|
||||
|
||||
@@ -38,6 +38,11 @@ import de.srsoftware.tools.gui.SelectComboBox;
|
||||
|
||||
import static de.srsoftware.belegscanner.Application.*;
|
||||
|
||||
/**
|
||||
* create the application's toolbar
|
||||
* @author Stephan Richter <s.richter@srsoftware.de>
|
||||
*
|
||||
*/
|
||||
public class Toolbar extends JPanel {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(Toolbar.class);
|
||||
@@ -91,6 +96,10 @@ public class Toolbar extends JPanel {
|
||||
private SelectComboBox catPicker;
|
||||
private int resolution = 150;
|
||||
|
||||
/**
|
||||
* create toolbar
|
||||
* @param config
|
||||
*/
|
||||
public Toolbar(Configuration config) {
|
||||
this.config = config;
|
||||
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
|
||||
@@ -104,32 +113,59 @@ public class Toolbar extends JPanel {
|
||||
Arrays.stream(getComponents()).filter(c -> c instanceof JPanel).map(JPanel.class::cast).forEach(p -> p.setBorder(BORDER));
|
||||
}
|
||||
|
||||
|
||||
private JPanel resolutionSelector() {
|
||||
ButtonGroup group = new ButtonGroup();
|
||||
JPanel resolutionSelector = new JPanel(new BorderLayout());
|
||||
JLabel label = new JLabel(t("current resolution")+": "+resolution+"px");
|
||||
resolutionSelector.add(label, BorderLayout.NORTH);
|
||||
resolutionSelector.add(resolutionButton(group,label,150),BorderLayout.WEST);
|
||||
resolutionSelector.add(resolutionButton(group,label,300),BorderLayout.CENTER);
|
||||
resolutionSelector.add(resolutionButton(group,label,600),BorderLayout.EAST);
|
||||
resolutionSelector.setMaximumSize(new Dimension(600,200));
|
||||
return resolutionSelector;
|
||||
/**
|
||||
* add a listener for updates of the categoriy field
|
||||
* @param listener
|
||||
* @return
|
||||
*/
|
||||
public Toolbar addCategoryListener(CategoryListener listener) {
|
||||
categoryListeners.add(listener);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
private JRadioButton resolutionButton(ButtonGroup group, JLabel label, int i) {
|
||||
JRadioButton btn = new JRadioButton(i+" px");
|
||||
btn.addActionListener(ev -> {
|
||||
resolution = i;
|
||||
label.setText("aktuelle Auflösung: "+resolution+"px");
|
||||
});
|
||||
group.add(btn);
|
||||
if (i==150) btn.setSelected(true);
|
||||
return btn;
|
||||
|
||||
/**
|
||||
* add a listener for updates of the date selector
|
||||
* @param listener
|
||||
* @return
|
||||
*/
|
||||
public Toolbar addDateListener(DateListener listener) {
|
||||
dateListeners.add(listener);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* add a listener for changes to the dimension form
|
||||
* @param listener
|
||||
* @return
|
||||
*/
|
||||
public Toolbar addDimensionListener(DimensionListener listener) {
|
||||
dimensionListeners.add(listener);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* add an input field for a variable placeholder
|
||||
* @param marks
|
||||
*/
|
||||
public void addFieldsFor(Vector<String> marks) {
|
||||
LOG.debug("addFieldsFor({})",marks);
|
||||
|
||||
List<String> deleted = additonalComponents.keySet().stream().filter(key -> !marks.contains(key)).collect(Collectors.toList());
|
||||
deleted.forEach(name -> remove(additonalComponents.remove(name)));
|
||||
|
||||
for (String name : marks) {
|
||||
if (additonalComponents.containsKey(name)) continue;
|
||||
SelectComboBox valuePicker = new SelectComboBox(new Vector<>()).onUpdateText(newText -> updateField(name,newText));
|
||||
JPanel input = input(name, valuePicker);
|
||||
input.setBorder(BORDER);
|
||||
add(input,getComponentCount()-OFFSET);
|
||||
additonalComponents.put(name, input);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add a form that enables the user to set the size of the scanning area
|
||||
*/
|
||||
private void addFormatSelector() {
|
||||
JPanel dummy = new JPanel();
|
||||
dummy.setLayout(new BorderLayout());
|
||||
@@ -160,53 +196,46 @@ public class Toolbar extends JPanel {
|
||||
height.addKeyListener(dimensionListener);
|
||||
}
|
||||
|
||||
public void addFieldsFor(Vector<String> marks) {
|
||||
LOG.debug("addFieldsFor({})",marks);
|
||||
|
||||
List<String> deleted = additonalComponents.keySet().stream().filter(key -> !marks.contains(key)).collect(Collectors.toList());
|
||||
deleted.forEach(name -> remove(additonalComponents.remove(name)));
|
||||
|
||||
for (String name : marks) {
|
||||
if (additonalComponents.containsKey(name)) continue;
|
||||
SelectComboBox valuePicker = new SelectComboBox(new Vector<>()).onUpdateText(newText -> updateField(name,newText));
|
||||
JPanel input = input(name, valuePicker);
|
||||
input.setBorder(BORDER);
|
||||
add(input,getComponentCount()-OFFSET);
|
||||
additonalComponents.put(name, input);
|
||||
}
|
||||
}
|
||||
|
||||
public Toolbar addCategoryListener(CategoryListener listener) {
|
||||
categoryListeners.add(listener);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Toolbar addDateListener(DateListener listener) {
|
||||
dateListeners.add(listener);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Toolbar addDimensionListener(DimensionListener listener) {
|
||||
dimensionListeners.add(listener);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* add a listener for updates of the variable fields
|
||||
* @param listener
|
||||
* @return
|
||||
*/
|
||||
public Toolbar addFieldListener(FieldListener listener) {
|
||||
fieldListeners.add(listener);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* add a listener for updates of the target path
|
||||
* @param listener
|
||||
* @return
|
||||
*/
|
||||
public Toolbar addPathListener(PathListener listener){
|
||||
pathListeners.add(listener);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* add a listener for the scan button
|
||||
* @param listener
|
||||
* @return
|
||||
*/
|
||||
public Toolbar addScanListener(ActionListener listener) {
|
||||
scanListeners.add(listener);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* create a auto complete text field for the category selection
|
||||
* @param config
|
||||
* @return
|
||||
*/
|
||||
private SelectComboBox categoryPicker(Configuration config) {
|
||||
JSONObject elements = config.getOrCreate("app.categories",new JSONObject());
|
||||
return new SelectComboBox(elements.keySet())
|
||||
@@ -214,6 +243,10 @@ public class Toolbar extends JPanel {
|
||||
.onDelete(this::dropCategory);
|
||||
}
|
||||
|
||||
/**
|
||||
* create the date picker
|
||||
* @return
|
||||
*/
|
||||
private Component datePicker() {
|
||||
date = new DateChooser();
|
||||
Dimension dim = new Dimension(400, 250);
|
||||
@@ -222,6 +255,12 @@ public class Toolbar extends JPanel {
|
||||
return date;
|
||||
}
|
||||
|
||||
/**
|
||||
* delete a value (by key) from a JSONArray
|
||||
* @param arr
|
||||
* @param tx
|
||||
* @return
|
||||
*/
|
||||
private List<Object> deleteValue(JSONArray arr, String tx) {
|
||||
for (int i = 0; i<arr.length(); i++) {
|
||||
if (arr.get(i).equals(tx)) {
|
||||
@@ -232,6 +271,10 @@ public class Toolbar extends JPanel {
|
||||
return arr.toList();
|
||||
}
|
||||
|
||||
/**
|
||||
* drop a category from the category pickers list of known categories
|
||||
* @param catName
|
||||
*/
|
||||
private void dropCategory(String catName) {
|
||||
LOG.debug("dropCategory({})",catName);
|
||||
Object o = config.get("app.categories");
|
||||
@@ -242,15 +285,28 @@ public class Toolbar extends JPanel {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get date from the date picker
|
||||
* @return
|
||||
*/
|
||||
public Date getDate() {
|
||||
return date.getSelectedDate();
|
||||
}
|
||||
|
||||
/**
|
||||
* get resolution (set by resoultion form)
|
||||
* @return
|
||||
*/
|
||||
public int getResolution() {
|
||||
return resolution;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* helper: returns the selector added as the second component of a JPanel
|
||||
* @param panel
|
||||
* @return null, of the panel has less than two children or the second child is no selector
|
||||
*/
|
||||
public SelectComboBox getSelector(JPanel panel) {
|
||||
if (panel != null && panel.getComponentCount()>1) {
|
||||
Component child = panel.getComponent(1);
|
||||
@@ -260,6 +316,12 @@ public class Toolbar extends JPanel {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* creates a labeled input field
|
||||
* @param caption
|
||||
* @param component
|
||||
* @return
|
||||
*/
|
||||
private JPanel input(String caption, JComponent component) {
|
||||
component.setMaximumSize(new Dimension(600, 40));
|
||||
component.setToolTipText(t("Press Shift + Delete to remove an entry."));
|
||||
@@ -270,6 +332,10 @@ public class Toolbar extends JPanel {
|
||||
return panel;
|
||||
}
|
||||
|
||||
/**
|
||||
* creates an auto-complete text field for setting the scan target path
|
||||
* @return
|
||||
*/
|
||||
private SelectComboBox pathPicker() {
|
||||
JSONObject cats = config.getOrCreate("app.categories",new JSONObject());
|
||||
for (String catName : cats.keySet()) {
|
||||
@@ -280,23 +346,69 @@ public class Toolbar extends JPanel {
|
||||
return new SelectComboBox(paths).onUpdateText(this::updatePath);
|
||||
}
|
||||
|
||||
/**
|
||||
* enables/disables the toolbars scan button
|
||||
* @param val
|
||||
*/
|
||||
public void readyToScan(boolean val) {
|
||||
scanButton.setEnabled(val);
|
||||
}
|
||||
/**
|
||||
* create one radio button for the resoultionSelector
|
||||
* @param group
|
||||
* @param label
|
||||
* @param i
|
||||
* @return
|
||||
*/
|
||||
private JRadioButton resolutionButton(ButtonGroup group, JLabel label, int i) {
|
||||
JRadioButton btn = new JRadioButton(i+" px");
|
||||
btn.addActionListener(ev -> {
|
||||
resolution = i;
|
||||
label.setText("aktuelle Auflösung: "+resolution+"px");
|
||||
});
|
||||
group.add(btn);
|
||||
if (i==150) btn.setSelected(true);
|
||||
return btn;
|
||||
}
|
||||
|
||||
/**
|
||||
* create a small for to select the resolution for scanning
|
||||
* @return
|
||||
*/
|
||||
private JPanel resolutionSelector() {
|
||||
ButtonGroup group = new ButtonGroup();
|
||||
JPanel resolutionSelector = new JPanel(new BorderLayout());
|
||||
JLabel label = new JLabel(t("current resolution")+": "+resolution+"px");
|
||||
resolutionSelector.add(label, BorderLayout.NORTH);
|
||||
resolutionSelector.add(resolutionButton(group,label,150),BorderLayout.WEST);
|
||||
resolutionSelector.add(resolutionButton(group,label,300),BorderLayout.CENTER);
|
||||
resolutionSelector.add(resolutionButton(group,label,600),BorderLayout.EAST);
|
||||
resolutionSelector.setMaximumSize(new Dimension(600,200));
|
||||
return resolutionSelector;
|
||||
}
|
||||
|
||||
/**
|
||||
* create scan button
|
||||
* @return
|
||||
*/
|
||||
private Component scanButton() {
|
||||
scanButton = new JButton(t("scan!"));
|
||||
scanButton.addActionListener(this::scanPressed);
|
||||
return scanButton;
|
||||
}
|
||||
|
||||
/**
|
||||
* notify listeners when scan button clicked
|
||||
* @param evt
|
||||
*/
|
||||
private void scanPressed(ActionEvent evt) {
|
||||
scanListeners.forEach(l->l.actionPerformed(evt));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* category updated: notify listeners and update dependent fields
|
||||
* @param newCat
|
||||
*/
|
||||
private void updateCat(String newCat) {
|
||||
LOG.debug("updateCat({})",newCat);
|
||||
categoryListeners.forEach(l -> l.setCategory(newCat));
|
||||
@@ -334,6 +446,9 @@ public class Toolbar extends JPanel {
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* read new dimension from dimension form, notify listeners
|
||||
*/
|
||||
protected void updateDimensions() {
|
||||
LOG.debug("updateDimensions()");
|
||||
try {
|
||||
@@ -346,12 +461,21 @@ public class Toolbar extends JPanel {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* notify listeners of changes to the variable field's values
|
||||
* @param name
|
||||
* @param val
|
||||
*/
|
||||
private void updateField(String name, String val) {
|
||||
LOG.debug("updateField({},{})",name,val);
|
||||
fieldListeners.forEach(l -> l.setField(name,val));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* notify listeners of changes to the path field
|
||||
* @param newPath
|
||||
*/
|
||||
protected void updatePath(String newPath) {
|
||||
LOG.debug("updatePath({})",newPath);
|
||||
pathListeners.forEach(l -> l.setPath(newPath));
|
||||
|
||||
Reference in New Issue
Block a user