implemented handling of jpeg files
This commit is contained in:
2
pom.xml
2
pom.xml
@@ -4,7 +4,7 @@
|
|||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>BelegScanner</groupId>
|
<groupId>BelegScanner</groupId>
|
||||||
<artifactId>BelegScanner</artifactId>
|
<artifactId>BelegScanner</artifactId>
|
||||||
<version>1.0.7</version>
|
<version>1.0.8</version>
|
||||||
|
|
||||||
<name>BelegScanner</name>
|
<name>BelegScanner</name>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ current resolution : aktuelle Auflösung
|
|||||||
DAY : TAG
|
DAY : TAG
|
||||||
Directory : Ordner
|
Directory : Ordner
|
||||||
display preview : Vorschau anzeigen
|
display preview : Vorschau anzeigen
|
||||||
|
drop file : Datei löschen
|
||||||
done : fertig
|
done : fertig
|
||||||
Error code\: {} for {} : Fehlercode: {} für {}
|
Error code\: {} for {} : Fehlercode: {} für {}
|
||||||
Finished text recognition. : Texterkennung beendet.
|
Finished text recognition. : Texterkennung beendet.
|
||||||
@@ -25,6 +26,7 @@ Scan failed. : Scannen fehlgeschlagen.
|
|||||||
Scanning… : Scanne…
|
Scanning… : Scanne…
|
||||||
scan! : scannen!
|
scan! : scannen!
|
||||||
State : Status
|
State : Status
|
||||||
|
Target type : Zieltyp
|
||||||
{} terminated\: : {} abgebrochen:
|
{} terminated\: : {} abgebrochen:
|
||||||
Text recognition… : Texterkennung…
|
Text recognition… : Texterkennung…
|
||||||
This application requires the following helper commands to be installed\: : Diese Anwendung erfordert es, dass auch die folgenden Hilfsprogramme installiert sind:
|
This application requires the following helper commands to be installed\: : Diese Anwendung erfordert es, dass auch die folgenden Hilfsprogramme installiert sind:
|
||||||
|
|||||||
@@ -3,8 +3,12 @@ package de.srsoftware.belegscanner;
|
|||||||
public class Constants {
|
public class Constants {
|
||||||
|
|
||||||
public static final String APPLICATION_NAME = "BelegScanner";
|
public static final String APPLICATION_NAME = "BelegScanner";
|
||||||
public static final String FILE_BROWSER = "thunar";
|
public static final String CONFIG_TARGET = "app.main.target";
|
||||||
public static final String DEFAULT_WIDTH = "209";
|
public static final String DEFAULT_WIDTH = "209";
|
||||||
public static final String DEFAULT_HEIGHT = "297";
|
public static final String DEFAULT_HEIGHT = "297";
|
||||||
|
public static final String FILE_BROWSER = "thunar";
|
||||||
|
public static final String JPG = "jpeg";
|
||||||
|
public static final String OCR = "pdf+ocr";
|
||||||
|
public static final String PDF = "pdf";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package de.srsoftware.belegscanner.gui;
|
package de.srsoftware.belegscanner.gui;
|
||||||
|
|
||||||
|
import static de.srsoftware.belegscanner.Application.t;
|
||||||
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.FlowLayout;
|
import java.awt.FlowLayout;
|
||||||
import java.awt.Font;
|
import java.awt.Font;
|
||||||
@@ -29,7 +31,6 @@ import org.slf4j.Logger;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import de.srsoftware.belegscanner.Constants;
|
import de.srsoftware.belegscanner.Constants;
|
||||||
import static de.srsoftware.belegscanner.Application.*;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@@ -40,13 +41,12 @@ import static de.srsoftware.belegscanner.Application.*;
|
|||||||
public class DocTable extends JPanel{
|
public class DocTable extends JPanel{
|
||||||
|
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(DocTable.class);
|
private static final Logger LOG = LoggerFactory.getLogger(DocTable.class);
|
||||||
private static FilenameFilter PAGES = (dir,name) -> name.toLowerCase().endsWith("pdf") && name.toLowerCase().startsWith("page");
|
private static FilenameFilter PAGES = (dir,name) -> name.toLowerCase().endsWith("pdf") && name.toLowerCase().contains("page");
|
||||||
private static FilenameFilter PDFS = (dir,name) -> name.toLowerCase().endsWith("pdf");
|
|
||||||
private static int rowCounter = 0;
|
private static int rowCounter = 0;
|
||||||
private static Font btnFont = new Font("Arial", Font.PLAIN, 28);
|
private static Font btnFont = new Font("Arial", Font.PLAIN, 28);
|
||||||
|
|
||||||
public interface PreviewListener{
|
public interface PreviewListener{
|
||||||
public void show(String filename);
|
public void show(Path filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -78,13 +78,12 @@ public class DocTable extends JPanel{
|
|||||||
buttons.add(joinButton = button("⎗",t("join PDFs"),ev -> joinDocs(path)));
|
buttons.add(joinButton = button("⎗",t("join PDFs"),ev -> joinDocs(path)));
|
||||||
buttons.add(button("🖻",t("display preview"),ev -> preview(path)));
|
buttons.add(button("🖻",t("display preview"),ev -> preview(path)));
|
||||||
buttons.add(button("✓",t("done"),ev -> drop(this)));
|
buttons.add(button("✓",t("done"),ev -> drop(this)));
|
||||||
|
buttons.add(button("❌",t("drop file"),ev -> dropFile(path)));
|
||||||
|
|
||||||
constraints.gridx = 2;
|
constraints.gridx = 2;
|
||||||
add(buttons,constraints);
|
add(buttons,constraints);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* drop the selected document from the table
|
* drop the selected document from the table
|
||||||
* @param row
|
* @param row
|
||||||
@@ -181,6 +180,18 @@ public class DocTable extends JPanel{
|
|||||||
return btn;
|
return btn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static int compareFiles(String file1, String file2) {
|
||||||
|
return timestampFrom(file1) < timestampFrom(file2) ? 1 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void dropFile(String path) {
|
||||||
|
Path latest = latestFile(path);
|
||||||
|
if (latest != null) {
|
||||||
|
latest.toFile().delete();
|
||||||
|
preview(path); // show lates of remaining files
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* join documents in given path
|
* join documents in given path
|
||||||
* @param path
|
* @param path
|
||||||
@@ -217,6 +228,14 @@ public class DocTable extends JPanel{
|
|||||||
setState(path,t("PDFs joined."));
|
setState(path,t("PDFs joined."));
|
||||||
preview(path);
|
preview(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Path latestFile(String path) {
|
||||||
|
File folder = new File(path);
|
||||||
|
if (!folder.exists()) return null;
|
||||||
|
List<String> files = Arrays.asList(folder.list());
|
||||||
|
String latest = files.stream().sorted(DocTable::compareFiles).findFirst().orElse(null);
|
||||||
|
return latest == null ? null : Path.of(path,latest);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* open given path in external file browser
|
* open given path in external file browser
|
||||||
@@ -245,11 +264,7 @@ public class DocTable extends JPanel{
|
|||||||
*/
|
*/
|
||||||
public void preview(String path) {
|
public void preview(String path) {
|
||||||
LOG.debug("preview({})",path);
|
LOG.debug("preview({})",path);
|
||||||
File folder = new File(path);
|
previewListeners.forEach(l -> l.show(latestFile(path)));
|
||||||
if (!folder.exists()) return;
|
|
||||||
List<String> pdfs = Arrays.asList(folder.list(PDFS));
|
|
||||||
LOG.debug("PDFs: {}",pdfs);
|
|
||||||
if (!pdfs.isEmpty()) previewListeners.forEach(l -> l.show(Path.of(path,pdfs.get(0)).toString()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -260,5 +275,12 @@ public class DocTable extends JPanel{
|
|||||||
public void setState(String path, String state) {
|
public void setState(String path, String state) {
|
||||||
Row row = rows.get(path);
|
Row row = rows.get(path);
|
||||||
if (row != null) row.status(state);
|
if (row != null) row.status(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static long timestampFrom(String filename) {
|
||||||
|
try {
|
||||||
|
return Long.parseLong(filename.split("\\.",2)[0]);
|
||||||
|
} catch (Exception e) {}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,20 +1,35 @@
|
|||||||
package de.srsoftware.belegscanner.gui;
|
package de.srsoftware.belegscanner.gui;
|
||||||
|
|
||||||
|
import static de.srsoftware.belegscanner.Application.t;
|
||||||
|
import static de.srsoftware.belegscanner.Constants.CONFIG_TARGET;
|
||||||
|
import static de.srsoftware.belegscanner.Constants.FILE_BROWSER;
|
||||||
|
import static de.srsoftware.belegscanner.Constants.JPG;
|
||||||
|
import static de.srsoftware.belegscanner.Constants.PDF;
|
||||||
|
|
||||||
import java.awt.BorderLayout;
|
import java.awt.BorderLayout;
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
|
import java.awt.Image;
|
||||||
import java.awt.Point;
|
import java.awt.Point;
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.*;
|
import java.util.Arrays;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
import java.util.Vector;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
import javax.swing.BorderFactory;
|
import javax.swing.BorderFactory;
|
||||||
|
import javax.swing.ImageIcon;
|
||||||
|
import javax.swing.JComponent;
|
||||||
import javax.swing.JFrame;
|
import javax.swing.JFrame;
|
||||||
import javax.swing.JLabel;
|
import javax.swing.JLabel;
|
||||||
import javax.swing.JOptionPane;
|
import javax.swing.JOptionPane;
|
||||||
@@ -29,10 +44,7 @@ import org.json.JSONArray;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import static de.srsoftware.belegscanner.Application.*;
|
|
||||||
import de.srsoftware.belegscanner.Configuration;
|
import de.srsoftware.belegscanner.Configuration;
|
||||||
import de.srsoftware.belegscanner.Constants;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The "guts" of the application:
|
* The "guts" of the application:
|
||||||
@@ -46,7 +58,7 @@ public class MainFrame extends JFrame {
|
|||||||
private static final long serialVersionUID = 210283601541223645L;
|
private static final long serialVersionUID = 210283601541223645L;
|
||||||
|
|
||||||
private static final String HOME = System.getProperty("user.home");
|
private static final String HOME = System.getProperty("user.home");
|
||||||
private static final Pattern MARKEN = Pattern.compile("\\$([a-zA-Z]+)");
|
private static final Pattern MARKEN = Pattern.compile("\\$([a-zäöüA-ZÄÖÜ]+)");
|
||||||
|
|
||||||
private static final String APP_WIDTH = "app.main.dimension.w";
|
private static final String APP_WIDTH = "app.main.dimension.w";
|
||||||
|
|
||||||
@@ -83,6 +95,10 @@ public class MainFrame extends JFrame {
|
|||||||
|
|
||||||
private boolean isScanning = false;
|
private boolean isScanning = false;
|
||||||
|
|
||||||
|
private JComponent previewComponent = null;
|
||||||
|
|
||||||
|
private JPanel pdfPreview;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create application main frame.
|
* Create application main frame.
|
||||||
* @param config
|
* @param config
|
||||||
@@ -103,7 +119,9 @@ public class MainFrame extends JFrame {
|
|||||||
add(toolbar,BorderLayout.EAST);
|
add(toolbar,BorderLayout.EAST);
|
||||||
add(statusBar,BorderLayout.SOUTH);
|
add(statusBar,BorderLayout.SOUTH);
|
||||||
add(docTable,BorderLayout.NORTH);
|
add(docTable,BorderLayout.NORTH);
|
||||||
add(preview(),BorderLayout.CENTER);
|
pdfPreview = preview();
|
||||||
|
add(previewComponent = pdfPreview,BorderLayout.CENTER);
|
||||||
|
|
||||||
toolbar.addCategoryListener(this::setCategory)
|
toolbar.addCategoryListener(this::setCategory)
|
||||||
.addDateListener(this::setDate)
|
.addDateListener(this::setDate)
|
||||||
.addDimensionListener(this::setDimension)
|
.addDimensionListener(this::setDimension)
|
||||||
@@ -138,7 +156,7 @@ public class MainFrame extends JFrame {
|
|||||||
};
|
};
|
||||||
|
|
||||||
public void checkDependencies() {
|
public void checkDependencies() {
|
||||||
List<String> missing = List.of("convert --version", "killall --version", "pdfsandwich -version", "pdftk --version", "scanimage --version",Constants.FILE_BROWSER+" --version").stream().map(this::appMissing).filter(app -> app != null).collect(Collectors.toList());
|
List<String> missing = List.of("convert --version", "killall --version", "pdfsandwich -version", "pdftk --version", "scanimage --version",FILE_BROWSER+" --version").stream().map(this::appMissing).filter(app -> app != null).collect(Collectors.toList());
|
||||||
if (!missing.isEmpty()) notifyAppsMissing(missing);
|
if (!missing.isEmpty()) notifyAppsMissing(missing);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -185,6 +203,9 @@ public class MainFrame extends JFrame {
|
|||||||
*/
|
*/
|
||||||
private void performScan(String path, Dimension dimension) {
|
private void performScan(String path, Dimension dimension) {
|
||||||
LOG.debug("performScan({})",path);
|
LOG.debug("performScan({})",path);
|
||||||
|
/* We need to all required config values before starting to scan, because the might be changed during scanning */
|
||||||
|
String target = config.getOrCreate(CONFIG_TARGET, "pdf");
|
||||||
|
|
||||||
setScanning(true);
|
setScanning(true);
|
||||||
|
|
||||||
File folder = new File(path);
|
File folder = new File(path);
|
||||||
@@ -230,8 +251,13 @@ public class MainFrame extends JFrame {
|
|||||||
LOG.error(t("{} terminated: "),builder,e);
|
LOG.error(t("{} terminated: "),builder,e);
|
||||||
}
|
}
|
||||||
setScanning(false);
|
setScanning(false);
|
||||||
|
if (JPG.equals(target)) {
|
||||||
|
docTable.setState(path, t("Image scanned"));
|
||||||
|
docTable.preview(path);
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
String pdf = "page."+timestamp+".pdf";
|
String pdf = timestamp+".page.pdf";
|
||||||
cmd = new Vector<>();
|
cmd = new Vector<>();
|
||||||
cmd.add("convert");
|
cmd.add("convert");
|
||||||
cmd.add(raw);
|
cmd.add(raw);
|
||||||
@@ -253,8 +279,13 @@ public class MainFrame extends JFrame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Path.of(path, raw).toFile().delete();
|
Path.of(path, raw).toFile().delete();
|
||||||
|
if (PDF.equals(target)) {
|
||||||
String ocr = "page."+timestamp+".ocr.pdf";
|
docTable.setState(path, t("PDF created"));
|
||||||
|
docTable.preview(path);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String ocr = timestamp+".page.ocr.pdf";
|
||||||
|
|
||||||
cmd = new Vector<>();
|
cmd = new Vector<>();
|
||||||
cmd.add("pdfsandwich");
|
cmd.add("pdfsandwich");
|
||||||
@@ -319,9 +350,37 @@ public class MainFrame extends JFrame {
|
|||||||
* open file in preview panel
|
* open file in preview panel
|
||||||
* @param file
|
* @param file
|
||||||
*/
|
*/
|
||||||
private void preview(String file) {
|
private void preview(Path filePath) {
|
||||||
pdfViewer.openDocument(file);
|
if (filePath == null) return;
|
||||||
pdfViewer.setPageFitMode(DocumentViewController.PAGE_FIT_WINDOW_HEIGHT, false);
|
String file = filePath.toString();
|
||||||
|
if (file.toLowerCase().endsWith("pdf")) {
|
||||||
|
if (previewComponent != pdfPreview) {
|
||||||
|
remove(previewComponent);
|
||||||
|
previewComponent = pdfPreview;
|
||||||
|
add(previewComponent,BorderLayout.CENTER);
|
||||||
|
pack();
|
||||||
|
}
|
||||||
|
pdfViewer.openDocument(file);
|
||||||
|
pdfViewer.setPageFitMode(DocumentViewController.PAGE_FIT_WINDOW_HEIGHT, false);
|
||||||
|
}
|
||||||
|
if (file.toLowerCase().endsWith("jpg")) {
|
||||||
|
try {
|
||||||
|
Image img = ImageIO.read(new File(file));
|
||||||
|
Dimension dim = previewComponent.getSize();
|
||||||
|
double w = img.getWidth(null);
|
||||||
|
double h = img.getHeight(null);
|
||||||
|
double factor = Math.min(dim.width/w, dim.height/h);
|
||||||
|
if (factor != 1.0) img = img.getScaledInstance((int)(w*factor), (int)(h*factor), Image.SCALE_DEFAULT);
|
||||||
|
ImageIcon icon = new ImageIcon(img);
|
||||||
|
JLabel label = new JLabel(icon);
|
||||||
|
this.remove(previewComponent);
|
||||||
|
previewComponent = label;
|
||||||
|
this.add(previewComponent, BorderLayout.CENTER);
|
||||||
|
pack();
|
||||||
|
} catch (IOException e) {
|
||||||
|
LOG.error("Was not able to preview {}:",file,e);
|
||||||
|
}
|
||||||
|
}
|
||||||
fileName.setText(file);
|
fileName.setText(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ import de.srsoftware.tools.gui.DateChooser;
|
|||||||
import de.srsoftware.tools.gui.SelectComboBox;
|
import de.srsoftware.tools.gui.SelectComboBox;
|
||||||
|
|
||||||
import static de.srsoftware.belegscanner.Application.*;
|
import static de.srsoftware.belegscanner.Application.*;
|
||||||
|
import static de.srsoftware.belegscanner.Constants.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* create the application's toolbar
|
* create the application's toolbar
|
||||||
@@ -95,7 +96,7 @@ public class Toolbar extends JPanel {
|
|||||||
private JTextField height;
|
private JTextField height;
|
||||||
private SelectComboBox catPicker;
|
private SelectComboBox catPicker;
|
||||||
private int resolution = 150;
|
private int resolution = 150;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* create toolbar
|
* create toolbar
|
||||||
* @param config
|
* @param config
|
||||||
@@ -108,6 +109,7 @@ public class Toolbar extends JPanel {
|
|||||||
add(input(t("Path"),pathPicker = pathPicker()));
|
add(input(t("Path"),pathPicker = pathPicker()));
|
||||||
addFormatSelector();
|
addFormatSelector();
|
||||||
add(resolutionSelector());
|
add(resolutionSelector());
|
||||||
|
add(typeSelector());
|
||||||
add(scanButton());
|
add(scanButton());
|
||||||
add(Box.createGlue());
|
add(Box.createGlue());
|
||||||
Arrays.stream(getComponents()).filter(c -> c instanceof JPanel).map(JPanel.class::cast).forEach(p -> p.setBorder(BORDER));
|
Arrays.stream(getComponents()).filter(c -> c instanceof JPanel).map(JPanel.class::cast).forEach(p -> p.setBorder(BORDER));
|
||||||
@@ -372,7 +374,7 @@ public class Toolbar extends JPanel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* create a small for to select the resolution for scanning
|
* create a radio group to select the resolution for scanning
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private JPanel resolutionSelector() {
|
private JPanel resolutionSelector() {
|
||||||
@@ -405,6 +407,42 @@ public class Toolbar extends JPanel {
|
|||||||
scanListeners.forEach(l->l.actionPerformed(evt));
|
scanListeners.forEach(l->l.actionPerformed(evt));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create one radio button for the typeSelector
|
||||||
|
* @param group
|
||||||
|
* @param label
|
||||||
|
* @param i
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private JRadioButton typeButton(ButtonGroup group, String label,String selection) {
|
||||||
|
JRadioButton btn = new JRadioButton(label);
|
||||||
|
group.add(btn);
|
||||||
|
btn.addActionListener(ev -> config.set(CONFIG_TARGET, label));
|
||||||
|
if (label.equals(selection)) btn.setSelected(true);
|
||||||
|
return btn;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create a radio group to select the target type for scanning
|
||||||
|
* @param jsonObject
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private JPanel typeSelector() {
|
||||||
|
ButtonGroup group = new ButtonGroup();
|
||||||
|
JPanel typeSelector = new JPanel(new BorderLayout());
|
||||||
|
JLabel label = new JLabel(t("Target type"));
|
||||||
|
String target = config.getOrCreate(CONFIG_TARGET, PDF);
|
||||||
|
typeSelector.add(label, BorderLayout.NORTH);
|
||||||
|
typeSelector.add(typeButton(group,t(JPG),target),BorderLayout.WEST);
|
||||||
|
typeSelector.add(typeButton(group,t(PDF),target),BorderLayout.CENTER);
|
||||||
|
typeSelector.add(typeButton(group,t(OCR),target),BorderLayout.EAST);
|
||||||
|
typeSelector.setMaximumSize(new Dimension(600,200));
|
||||||
|
return typeSelector;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* category updated: notify listeners and update dependent fields
|
* category updated: notify listeners and update dependent fields
|
||||||
* @param newCat
|
* @param newCat
|
||||||
|
|||||||
Reference in New Issue
Block a user