Add thresholding
This commit is contained in:
@@ -17,4 +17,5 @@ public interface INavigator {
|
||||
void showComplexMorphology();
|
||||
void showLinearOutline();
|
||||
void showNonLinearOutline();
|
||||
void showThresholding();
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import ui.implementation.views.morphology.BasicMorphologyView;
|
||||
import ui.implementation.views.morphology.ComplexMorphologyView;
|
||||
import ui.implementation.views.outline.LinearOutlineView;
|
||||
import ui.implementation.views.outline.NonLinearOutlineView;
|
||||
import ui.implementation.views.threshold.ThresholdingView;
|
||||
|
||||
/**
|
||||
* Concrete implement of the INavigator interface.
|
||||
@@ -29,6 +30,7 @@ public class SwingNavigator implements INavigator {
|
||||
private final Provider<ComplexMorphologyView> complexMorphologyProvider;
|
||||
private final Provider<LinearOutlineView> linearOutlineProvider;
|
||||
private final Provider<NonLinearOutlineView> nonLinearOutlineProvider;
|
||||
private final Provider<ThresholdingView> thresholdingProvider;
|
||||
|
||||
@Inject
|
||||
public SwingNavigator(
|
||||
@@ -39,7 +41,8 @@ public class SwingNavigator implements INavigator {
|
||||
Provider<BasicMorphologyView> basicMorphologyProvider,
|
||||
Provider<ComplexMorphologyView> complexMorphologyProvider,
|
||||
Provider<LinearOutlineView> linearOutlineProvider,
|
||||
Provider<NonLinearOutlineView> nonLinearOutlineProvider
|
||||
Provider<NonLinearOutlineView> nonLinearOutlineProvider,
|
||||
Provider<ThresholdingView> thresholdingProvider
|
||||
) {
|
||||
this.doubleMatrixProvider = doubleMatrixProvider;
|
||||
this.filteringProvider = filteringProvider;
|
||||
@@ -49,6 +52,7 @@ public class SwingNavigator implements INavigator {
|
||||
this.complexMorphologyProvider = complexMorphologyProvider;
|
||||
this.linearOutlineProvider = linearOutlineProvider;
|
||||
this.nonLinearOutlineProvider = nonLinearOutlineProvider;
|
||||
this.thresholdingProvider = thresholdingProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -99,6 +103,12 @@ public class SwingNavigator implements INavigator {
|
||||
runView(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showThresholding() {
|
||||
ThresholdingView view = thresholdingProvider.get();
|
||||
runView(view);
|
||||
}
|
||||
|
||||
private void runView(AbstractView view) {
|
||||
ViewInitializer.Initialize(view);
|
||||
view.setVisible(true);
|
||||
|
||||
65
src/main/java/app/state/ThresholdingState.java
Normal file
65
src/main/java/app/state/ThresholdingState.java
Normal file
@@ -0,0 +1,65 @@
|
||||
package app.state;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import domain.image.Image;
|
||||
import presenters.threshold.ThresholdingListener;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ThresholdingState extends State {
|
||||
|
||||
private Image simpleThreshold;
|
||||
private Image doubleThreshold;
|
||||
private Image automaticThreshold;
|
||||
|
||||
private final List<ThresholdingListener> listeners = new ArrayList<>();
|
||||
|
||||
@Inject
|
||||
public ThresholdingState() {
|
||||
}
|
||||
|
||||
public void subscribe(ThresholdingListener listener) {
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
public void unsubscribe(ThresholdingListener listener) {
|
||||
listeners.remove(listener);
|
||||
}
|
||||
|
||||
public void setSimpleThreshold(Image image) {
|
||||
simpleThreshold = image;
|
||||
|
||||
listeners.forEach(listener ->
|
||||
listener.onSimpleThresholdChanged(image)
|
||||
);
|
||||
}
|
||||
|
||||
public void setDoubleThreshold(Image image) {
|
||||
doubleThreshold = image;
|
||||
|
||||
listeners.forEach(listener ->
|
||||
listener.onDoubleThresholdChanged(image)
|
||||
);
|
||||
}
|
||||
|
||||
public void setAutomaticThreshold(Image image) {
|
||||
automaticThreshold = image;
|
||||
|
||||
listeners.forEach(listener ->
|
||||
listener.onAutomaticThresholdChanged(image)
|
||||
);
|
||||
}
|
||||
|
||||
public Image getSimpleThreshold() {
|
||||
return simpleThreshold;
|
||||
}
|
||||
|
||||
public Image getDoubleThreshold() {
|
||||
return doubleThreshold;
|
||||
}
|
||||
|
||||
public Image getAutomaticThreshold() {
|
||||
return automaticThreshold;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
package domain.image.processing.threshold;
|
||||
|
||||
import domain.image.GrayScaleMatrix;
|
||||
import domain.image.Image;
|
||||
|
||||
public class Thresholding {
|
||||
|
||||
public static GrayScaleMatrix simpleThreshold(
|
||||
Image image,
|
||||
int threshold
|
||||
) {
|
||||
GrayScaleMatrix gray = image.toGrayScale();
|
||||
|
||||
int height = gray.getHeight();
|
||||
int width = gray.getWidth();
|
||||
|
||||
double[][] data = gray.getRawData();
|
||||
double[][] result = new double[height][width];
|
||||
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
result[y][x] = data[y][x] >= threshold
|
||||
? 255
|
||||
: 0;
|
||||
}
|
||||
}
|
||||
|
||||
return new GrayScaleMatrix(result);
|
||||
}
|
||||
|
||||
public static GrayScaleMatrix doubleThreshold(
|
||||
Image image,
|
||||
int threshold1,
|
||||
int threshold2
|
||||
) {
|
||||
if (threshold1 > threshold2) {
|
||||
int temp = threshold1;
|
||||
threshold1 = threshold2;
|
||||
threshold2 = temp;
|
||||
}
|
||||
|
||||
GrayScaleMatrix gray = image.toGrayScale();
|
||||
|
||||
int height = gray.getHeight();
|
||||
int width = gray.getWidth();
|
||||
|
||||
double[][] data = gray.getRawData();
|
||||
double[][] result = new double[height][width];
|
||||
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
|
||||
double value = data[y][x];
|
||||
|
||||
if (value < threshold1) {
|
||||
result[y][x] = 0;
|
||||
} else if (value < threshold2) {
|
||||
result[y][x] = 127;
|
||||
} else {
|
||||
result[y][x] = 255;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new GrayScaleMatrix(result);
|
||||
}
|
||||
|
||||
public static GrayScaleMatrix automaticThreshold(Image image) {
|
||||
GrayScaleMatrix gray = image.toGrayScale();
|
||||
|
||||
double[][] data = gray.getRawData();
|
||||
|
||||
double threshold = (gray.getMinValue() + gray.getMaxValue()) / 2.0;
|
||||
|
||||
while (true) {
|
||||
double lowerSum = 0;
|
||||
double upperSum = 0;
|
||||
|
||||
int lowerCount = 0;
|
||||
int upperCount = 0;
|
||||
|
||||
for (int y = 0; y < gray.getHeight(); y++) {
|
||||
for (int x = 0; x < gray.getWidth(); x++) {
|
||||
|
||||
double value = data[y][x];
|
||||
|
||||
if (value <= threshold) {
|
||||
lowerSum += value;
|
||||
lowerCount++;
|
||||
} else {
|
||||
upperSum += value;
|
||||
upperCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (lowerCount == 0 || upperCount == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
double lowerMean = lowerSum / lowerCount;
|
||||
double upperMean = upperSum / upperCount;
|
||||
|
||||
double newThreshold = (lowerMean + upperMean) / 2.0;
|
||||
|
||||
if (Math.abs(newThreshold - threshold) < 0.5) {
|
||||
threshold = newThreshold;
|
||||
break;
|
||||
}
|
||||
|
||||
threshold = newThreshold;
|
||||
}
|
||||
|
||||
return simpleThreshold(image, (int) threshold);
|
||||
}
|
||||
}
|
||||
@@ -58,6 +58,8 @@ public class NavPresenter {
|
||||
|
||||
public void goToNonLinearOutline() { navigator.showNonLinearOutline(); }
|
||||
|
||||
public void goToThresholding() { navigator.showThresholding(); }
|
||||
|
||||
public GrayScaleMatrix getImageGrayMatrix() { return appState.getImage().toGrayScale(); }
|
||||
|
||||
public void setMode(Mode mode) { modeService.setMode(mode); }
|
||||
|
||||
12
src/main/java/presenters/threshold/ThresholdingListener.java
Normal file
12
src/main/java/presenters/threshold/ThresholdingListener.java
Normal file
@@ -0,0 +1,12 @@
|
||||
package presenters.threshold;
|
||||
|
||||
import domain.image.Image;
|
||||
|
||||
public interface ThresholdingListener {
|
||||
|
||||
void onSimpleThresholdChanged(Image image);
|
||||
|
||||
void onDoubleThresholdChanged(Image image);
|
||||
|
||||
void onAutomaticThresholdChanged(Image image);
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
package presenters.threshold;
|
||||
|
||||
import app.state.AppState;
|
||||
import app.state.ThresholdingState;
|
||||
import domain.image.Image;
|
||||
import jakarta.inject.Inject;
|
||||
import services.ThresholdingService;
|
||||
import ui.abstractions.IThresholdingView;
|
||||
|
||||
public class ThresholdingPresenter implements ThresholdingListener {
|
||||
|
||||
private final AppState appState;
|
||||
private final ThresholdingState thresholdingState;
|
||||
private final ThresholdingService thresholdingService;
|
||||
|
||||
private IThresholdingView view;
|
||||
|
||||
@Inject
|
||||
public ThresholdingPresenter(
|
||||
AppState appState,
|
||||
ThresholdingState thresholdingState,
|
||||
ThresholdingService thresholdingService
|
||||
) {
|
||||
this.appState = appState;
|
||||
this.thresholdingState = thresholdingState;
|
||||
this.thresholdingService = thresholdingService;
|
||||
|
||||
thresholdingState.subscribe(this);
|
||||
}
|
||||
|
||||
public void setView(IThresholdingView view) {
|
||||
this.view = view;
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
view = null;
|
||||
thresholdingState.unsubscribe(this);
|
||||
}
|
||||
|
||||
public void computeSimpleThreshold(int threshold) {
|
||||
Image image = appState.getImage();
|
||||
|
||||
Image result = thresholdingService.simpleThreshold(
|
||||
image,
|
||||
threshold
|
||||
);
|
||||
|
||||
thresholdingState.setSimpleThreshold(result);
|
||||
}
|
||||
|
||||
public void computeDoubleThreshold(
|
||||
int threshold1,
|
||||
int threshold2
|
||||
) {
|
||||
Image image = appState.getImage();
|
||||
|
||||
Image result = thresholdingService.doubleThreshold(
|
||||
image,
|
||||
threshold1,
|
||||
threshold2
|
||||
);
|
||||
|
||||
thresholdingState.setDoubleThreshold(result);
|
||||
}
|
||||
|
||||
public void computeAutomaticThreshold() {
|
||||
Image image = appState.getImage();
|
||||
|
||||
Image result = thresholdingService.automaticThreshold(image);
|
||||
|
||||
thresholdingState.setAutomaticThreshold(result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSimpleThresholdChanged(Image image) {
|
||||
if (view != null) {
|
||||
view.updateSimpleThreshold(image);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDoubleThresholdChanged(Image image) {
|
||||
if (view != null) {
|
||||
view.updateDoubleThreshold(image);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAutomaticThresholdChanged(Image image) {
|
||||
if (view != null) {
|
||||
view.updateAutomaticThreshold(image);
|
||||
}
|
||||
}
|
||||
}
|
||||
29
src/main/java/services/ThresholdingService.java
Normal file
29
src/main/java/services/ThresholdingService.java
Normal file
@@ -0,0 +1,29 @@
|
||||
package services;
|
||||
|
||||
import domain.image.Image;
|
||||
import domain.image.processing.threshold.Thresholding;
|
||||
|
||||
public class ThresholdingService {
|
||||
|
||||
public Image simpleThreshold(Image image, int threshold) {
|
||||
return Thresholding
|
||||
.simpleThreshold(image, threshold)
|
||||
.toImage();
|
||||
}
|
||||
|
||||
public Image doubleThreshold(
|
||||
Image image,
|
||||
int threshold1,
|
||||
int threshold2
|
||||
) {
|
||||
return Thresholding
|
||||
.doubleThreshold(image, threshold1, threshold2)
|
||||
.toImage();
|
||||
}
|
||||
|
||||
public Image automaticThreshold(Image image) {
|
||||
return Thresholding
|
||||
.automaticThreshold(image)
|
||||
.toImage();
|
||||
}
|
||||
}
|
||||
12
src/main/java/ui/abstractions/IThresholdingView.java
Normal file
12
src/main/java/ui/abstractions/IThresholdingView.java
Normal file
@@ -0,0 +1,12 @@
|
||||
package ui.abstractions;
|
||||
|
||||
import domain.image.Image;
|
||||
|
||||
public interface IThresholdingView {
|
||||
|
||||
void updateSimpleThreshold(Image image);
|
||||
|
||||
void updateDoubleThreshold(Image image);
|
||||
|
||||
void updateAutomaticThreshold(Image image);
|
||||
}
|
||||
@@ -33,9 +33,10 @@ public class NavBar extends JMenuBar implements INavBar {
|
||||
private JMenu drawingMenu;
|
||||
private JMenu fourierMenu;
|
||||
private JMenu linearMenu;
|
||||
private JMenu histogramMenu;
|
||||
private JMenu morphologyMenu;
|
||||
private Menu outlineMenu;
|
||||
private Menu thresholdingMenu;
|
||||
private JMenu histogramMenu;
|
||||
|
||||
private NavPresenter presenter;
|
||||
|
||||
@@ -103,6 +104,10 @@ public class NavBar extends JMenuBar implements INavBar {
|
||||
new MenuItem("Non-linéaire", this::displayNonLinearOutline)
|
||||
);
|
||||
|
||||
thresholdingMenu = new Menu("Seuillage","/cp_51_p1.jpg",
|
||||
new MenuItem("Afficher", this::displayThresholding)
|
||||
);
|
||||
|
||||
histogramMenu = new Menu("Histogramme","/report_48_hot.jpg",
|
||||
new MenuItem("Afficher", "/report_32_hot.jpg",this::displayHistogram)
|
||||
);
|
||||
@@ -113,6 +118,7 @@ public class NavBar extends JMenuBar implements INavBar {
|
||||
this.add(linearMenu);
|
||||
this.add(morphologyMenu);
|
||||
this.add(outlineMenu);
|
||||
this.add(thresholdingMenu);
|
||||
this.add(histogramMenu);
|
||||
|
||||
drawingMenu.setEnabled(false);
|
||||
@@ -120,9 +126,12 @@ public class NavBar extends JMenuBar implements INavBar {
|
||||
linearMenu.setEnabled(false);
|
||||
morphologyMenu.setEnabled(false);
|
||||
outlineMenu.setEnabled(false);
|
||||
thresholdingMenu.setEnabled(false);
|
||||
histogramMenu.setEnabled(false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//####################################################
|
||||
|
||||
private File chooseFile(){
|
||||
@@ -190,6 +199,7 @@ public class NavBar extends JMenuBar implements INavBar {
|
||||
linearMenu.setEnabled(true);
|
||||
morphologyMenu.setEnabled(true);
|
||||
outlineMenu.setEnabled(true);
|
||||
thresholdingMenu.setEnabled(true);
|
||||
histogramMenu.setEnabled(true);
|
||||
}
|
||||
|
||||
@@ -200,6 +210,7 @@ public class NavBar extends JMenuBar implements INavBar {
|
||||
linearMenu.setEnabled(false);
|
||||
morphologyMenu.setEnabled(false);
|
||||
outlineMenu.setEnabled(false);
|
||||
thresholdingMenu.setEnabled(false);
|
||||
histogramMenu.setEnabled(false);
|
||||
}
|
||||
|
||||
@@ -261,6 +272,7 @@ public class NavBar extends JMenuBar implements INavBar {
|
||||
|
||||
private void displayNonLinearOutline(ActionEvent actionEvent) { presenter.goToNonLinearOutline();}
|
||||
|
||||
private void displayThresholding(ActionEvent actionEvent) { presenter.goToThresholding(); }
|
||||
|
||||
private void displayErrorMessage(String title, String message) {
|
||||
JOptionPane.showMessageDialog(
|
||||
|
||||
@@ -0,0 +1,292 @@
|
||||
package ui.implementation.views.threshold;
|
||||
|
||||
import domain.image.Image;
|
||||
import jakarta.inject.Inject;
|
||||
import presenters.threshold.ThresholdingPresenter;
|
||||
import ui.abstractions.AbstractView;
|
||||
import ui.abstractions.IThresholdingView;
|
||||
import ui.implementation.components.controls.SaveButton;
|
||||
import ui.implementation.components.image.TabbedImagePanel;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
public class ThresholdingView extends AbstractView implements IThresholdingView {
|
||||
|
||||
private static final String SIMPLE_TAB_TITLE = "Simple";
|
||||
private static final String DOUBLE_TAB_TITLE = "Double";
|
||||
private static final String AUTOMATIC_TAB_TITLE = "Automatique";
|
||||
|
||||
private final ThresholdingPresenter presenter;
|
||||
|
||||
private TabbedImagePanel modeTab;
|
||||
|
||||
private JSlider thresholdSlider;
|
||||
private JSlider threshold1Slider;
|
||||
private JSlider threshold2Slider;
|
||||
|
||||
private JLabel thresholdValueLabel;
|
||||
private JLabel threshold1ValueLabel;
|
||||
private JLabel threshold2ValueLabel;
|
||||
|
||||
@Inject
|
||||
public ThresholdingView(ThresholdingPresenter presenter) {
|
||||
this.presenter = presenter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initComponents() {
|
||||
modeTab = new TabbedImagePanel();
|
||||
|
||||
modeTab.addPreviewTab(SIMPLE_TAB_TITLE);
|
||||
modeTab.addPreviewTab(DOUBLE_TAB_TITLE);
|
||||
modeTab.addPreviewTab(AUTOMATIC_TAB_TITLE);
|
||||
|
||||
thresholdSlider = createThresholdSlider(128);
|
||||
threshold1Slider = createThresholdSlider(85);
|
||||
threshold2Slider = createThresholdSlider(170);
|
||||
|
||||
thresholdValueLabel = new JLabel();
|
||||
threshold1ValueLabel = new JLabel();
|
||||
threshold2ValueLabel = new JLabel();
|
||||
|
||||
updateValueLabels();
|
||||
|
||||
thresholdSlider.addChangeListener(e -> {
|
||||
updateValueLabels();
|
||||
presenter.computeSimpleThreshold(
|
||||
thresholdSlider.getValue()
|
||||
);
|
||||
});
|
||||
|
||||
threshold1Slider.addChangeListener(e -> {
|
||||
if (threshold1Slider.getValue() > threshold2Slider.getValue()) {
|
||||
threshold2Slider.setValue(threshold1Slider.getValue());
|
||||
}
|
||||
|
||||
updateValueLabels();
|
||||
|
||||
presenter.computeDoubleThreshold(
|
||||
threshold1Slider.getValue(),
|
||||
threshold2Slider.getValue()
|
||||
);
|
||||
});
|
||||
|
||||
threshold2Slider.addChangeListener(e -> {
|
||||
if (threshold2Slider.getValue() < threshold1Slider.getValue()) {
|
||||
threshold1Slider.setValue(threshold2Slider.getValue());
|
||||
}
|
||||
|
||||
updateValueLabels();
|
||||
|
||||
presenter.computeDoubleThreshold(
|
||||
threshold1Slider.getValue(),
|
||||
threshold2Slider.getValue()
|
||||
);
|
||||
});
|
||||
|
||||
JButton saveButton = new SaveButton();
|
||||
|
||||
JPanel controlPanel = createControlPanel();
|
||||
|
||||
JPanel rightPanel = new JPanel();
|
||||
|
||||
GroupLayout rightLayout = new GroupLayout(rightPanel);
|
||||
rightPanel.setLayout(rightLayout);
|
||||
rightLayout.setAutoCreateGaps(true);
|
||||
rightLayout.setAutoCreateContainerGaps(true);
|
||||
|
||||
rightLayout.setHorizontalGroup(
|
||||
rightLayout.createParallelGroup(GroupLayout.Alignment.CENTER)
|
||||
.addComponent(controlPanel)
|
||||
.addComponent(saveButton)
|
||||
);
|
||||
|
||||
rightLayout.setVerticalGroup(
|
||||
rightLayout.createSequentialGroup()
|
||||
.addComponent(controlPanel)
|
||||
.addComponent(saveButton)
|
||||
);
|
||||
|
||||
JPanel mainPanel = new JPanel();
|
||||
|
||||
GroupLayout mainLayout = new GroupLayout(mainPanel);
|
||||
mainPanel.setLayout(mainLayout);
|
||||
mainLayout.setAutoCreateGaps(true);
|
||||
mainLayout.setAutoCreateContainerGaps(true);
|
||||
|
||||
mainLayout.setHorizontalGroup(
|
||||
mainLayout.createSequentialGroup()
|
||||
.addComponent(modeTab)
|
||||
.addComponent(rightPanel)
|
||||
);
|
||||
|
||||
mainLayout.setVerticalGroup(
|
||||
mainLayout.createParallelGroup(GroupLayout.Alignment.CENTER)
|
||||
.addComponent(modeTab)
|
||||
.addComponent(rightPanel)
|
||||
);
|
||||
|
||||
setContentPane(mainPanel);
|
||||
|
||||
setTitle("Seuillage");
|
||||
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
|
||||
pack();
|
||||
}
|
||||
|
||||
private JSlider createThresholdSlider(int value) {
|
||||
JSlider slider = new JSlider(
|
||||
SwingConstants.VERTICAL,
|
||||
0,
|
||||
255,
|
||||
value
|
||||
);
|
||||
|
||||
slider.setMajorTickSpacing(50);
|
||||
slider.setMinorTickSpacing(10);
|
||||
slider.setPaintTicks(true);
|
||||
slider.setPaintLabels(true);
|
||||
|
||||
slider.setLabelTable(slider.createStandardLabels(50));
|
||||
|
||||
return slider;
|
||||
}
|
||||
|
||||
private JPanel createControlPanel() {
|
||||
JPanel panel = new JPanel();
|
||||
|
||||
GroupLayout layout = new GroupLayout(panel);
|
||||
panel.setLayout(layout);
|
||||
layout.setAutoCreateGaps(true);
|
||||
layout.setAutoCreateContainerGaps(true);
|
||||
|
||||
JPanel simplePanel = createSliderPanel(
|
||||
thresholdSlider,
|
||||
thresholdValueLabel
|
||||
);
|
||||
|
||||
JPanel double1Panel = createSliderPanel(
|
||||
threshold1Slider,
|
||||
threshold1ValueLabel
|
||||
);
|
||||
|
||||
JPanel double2Panel = createSliderPanel(
|
||||
threshold2Slider,
|
||||
threshold2ValueLabel
|
||||
);
|
||||
|
||||
layout.setHorizontalGroup(
|
||||
layout.createSequentialGroup()
|
||||
.addComponent(simplePanel)
|
||||
.addComponent(double1Panel)
|
||||
.addComponent(double2Panel)
|
||||
);
|
||||
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(GroupLayout.Alignment.CENTER)
|
||||
.addComponent(simplePanel)
|
||||
.addComponent(double1Panel)
|
||||
.addComponent(double2Panel)
|
||||
);
|
||||
|
||||
return panel;
|
||||
}
|
||||
|
||||
private JPanel createSliderPanel(JSlider slider, JLabel valueLabel) {
|
||||
JPanel panel = new JPanel();
|
||||
|
||||
GroupLayout layout = new GroupLayout(panel);
|
||||
panel.setLayout(layout);
|
||||
layout.setAutoCreateGaps(true);
|
||||
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(GroupLayout.Alignment.CENTER)
|
||||
.addComponent(slider)
|
||||
.addComponent(valueLabel)
|
||||
);
|
||||
|
||||
layout.setVerticalGroup(
|
||||
layout.createSequentialGroup()
|
||||
.addComponent(slider)
|
||||
.addComponent(valueLabel)
|
||||
);
|
||||
|
||||
return panel;
|
||||
}
|
||||
|
||||
private void updateValueLabels() {
|
||||
thresholdValueLabel.setText(
|
||||
String.valueOf(thresholdSlider.getValue())
|
||||
);
|
||||
|
||||
threshold1ValueLabel.setText(
|
||||
String.valueOf(threshold1Slider.getValue())
|
||||
);
|
||||
|
||||
threshold2ValueLabel.setText(
|
||||
String.valueOf(threshold2Slider.getValue())
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initValues() {
|
||||
modeTab.addChangeListener(e -> {
|
||||
updateControls();
|
||||
applyThreshold();
|
||||
});
|
||||
|
||||
presenter.setView(this);
|
||||
|
||||
updateControls();
|
||||
applyThreshold();
|
||||
}
|
||||
|
||||
private void updateControls() {
|
||||
int operation = modeTab.getSelectedIndex();
|
||||
|
||||
thresholdSlider.setVisible(operation == 0);
|
||||
|
||||
threshold1Slider.setVisible(operation == 1);
|
||||
threshold2Slider.setVisible(operation == 1);
|
||||
|
||||
thresholdValueLabel.setVisible(operation == 0);
|
||||
|
||||
threshold1ValueLabel.setVisible(operation == 1);
|
||||
threshold2ValueLabel.setVisible(operation == 1);
|
||||
}
|
||||
|
||||
private void applyThreshold() {
|
||||
switch (modeTab.getSelectedIndex()) {
|
||||
case 0 -> presenter.computeSimpleThreshold(
|
||||
thresholdSlider.getValue()
|
||||
);
|
||||
|
||||
case 1 -> presenter.computeDoubleThreshold(
|
||||
threshold1Slider.getValue(),
|
||||
threshold2Slider.getValue()
|
||||
);
|
||||
|
||||
case 2 -> presenter.computeAutomaticThreshold();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateSimpleThreshold(Image image) {
|
||||
modeTab.loadImage(SIMPLE_TAB_TITLE, image);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDoubleThreshold(Image image) {
|
||||
modeTab.loadImage(DOUBLE_TAB_TITLE, image);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateAutomaticThreshold(Image image) {
|
||||
modeTab.loadImage(AUTOMATIC_TAB_TITLE, image);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disposeCore() {
|
||||
presenter.setView(null);
|
||||
presenter.dispose();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user