Image viewer application
This commit is contained in:
parent
15f7b2f2e9
commit
63d20d6f3e
@ -1,4 +1,29 @@
|
|||||||
package fr.uha.gabalier.controller;
|
package fr.uha.gabalier.controller;
|
||||||
|
|
||||||
public interface Controller {
|
import fr.uha.gabalier.view.View;
|
||||||
|
|
||||||
|
public class Controller<T> {
|
||||||
|
|
||||||
|
private T model;
|
||||||
|
private View view;
|
||||||
|
|
||||||
|
protected Controller(T model) {
|
||||||
|
this.model = model;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected T getModel() {
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setModel(T model) {
|
||||||
|
this.model = model;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected View getView() {
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setView(View v) {
|
||||||
|
this.view = v;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,58 @@
|
|||||||
|
package fr.uha.gabalier.controller;
|
||||||
|
|
||||||
|
import fr.uha.gabalier.view.Preview;
|
||||||
|
import fr.uha.gabalier.view.View;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ImageController<T> extends Controller<List<Image>> implements ActionListener {
|
||||||
|
|
||||||
|
private int index;
|
||||||
|
|
||||||
|
public ImageController(List<Image> newModel) {
|
||||||
|
super(newModel);
|
||||||
|
this.index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent evt) {
|
||||||
|
switch (evt.getActionCommand()) {
|
||||||
|
case Preview.LEFT_COMMAND :
|
||||||
|
doLeft();
|
||||||
|
break;
|
||||||
|
case Preview.RIGHT_COMMAND:
|
||||||
|
doRight();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doRight() {
|
||||||
|
if (getModel() == null) return;
|
||||||
|
if (getModel().size() == 0) return;
|
||||||
|
if (++index > getModel().size() - 1) index = 0;
|
||||||
|
getView().repaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doLeft() {
|
||||||
|
if (getModel() == null) return;
|
||||||
|
if (getModel().size() == 0) return;
|
||||||
|
if (--index < 0) index = getModel().size() - 1;
|
||||||
|
getView().repaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getIndex() {
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void resetIndex() {
|
||||||
|
this.index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setModel(List<Image> model) {
|
||||||
|
super.setModel(model);
|
||||||
|
this.index = 0;
|
||||||
|
}
|
||||||
|
}
|
@ -18,7 +18,7 @@ public class ImageLoader extends SwingWorker<List<Image>, Integer> {
|
|||||||
private List<Image> images;
|
private List<Image> images;
|
||||||
private final int iconWidth;
|
private final int iconWidth;
|
||||||
|
|
||||||
public ImageLoader(File root, Preview app, int iconWidth) {
|
public ImageLoader(Preview app, int iconWidth, File root) {
|
||||||
this.root = root;
|
this.root = root;
|
||||||
this.app = app;
|
this.app = app;
|
||||||
this.iconWidth = iconWidth;
|
this.iconWidth = iconWidth;
|
||||||
@ -51,14 +51,14 @@ public class ImageLoader extends SwingWorker<List<Image>, Integer> {
|
|||||||
@Override
|
@Override
|
||||||
protected void process(List<Integer> data) {
|
protected void process(List<Integer> data) {
|
||||||
if (this.isCancelled()) return;
|
if (this.isCancelled()) return;
|
||||||
app.setStatus(String.valueOf(data.get(data.size() - 1)));
|
app.setStatus(String.valueOf(data.get(data.size() - 1)) + " images loaded");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void done() {
|
protected void done() {
|
||||||
try {
|
try {
|
||||||
app.setModel(this.get());
|
app.setModel(this.get());
|
||||||
app.setStatus(app.getModel().size() + "images loaded");
|
app.setStatus(app.getModel().size() + " images loaded");
|
||||||
} catch (CancellationException e) {
|
} catch (CancellationException e) {
|
||||||
app.setStatus("Cancelled");
|
app.setStatus("Cancelled");
|
||||||
} catch (InterruptedException | ExecutionException e) {
|
} catch (InterruptedException | ExecutionException e) {
|
||||||
|
@ -1,11 +1,22 @@
|
|||||||
package fr.uha.gabalier.util;
|
package fr.uha.gabalier.util;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
public final class ImageLib {
|
public final class ImageLib {
|
||||||
|
|
||||||
public static Image createScaledImage(File file, int iconWidth, int i) {
|
public static Image createScaledImage(File file, int iconWidth, int iconHeight) {
|
||||||
|
final BufferedImage img;
|
||||||
|
try {
|
||||||
|
if ((img = ImageIO.read(file)) != null) {
|
||||||
|
return img.getScaledInstance(iconWidth, iconHeight, Image.SCALE_DEFAULT);
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
25
src/main/java/fr/uha/gabalier/view/ImageView.java
Normal file
25
src/main/java/fr/uha/gabalier/view/ImageView.java
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
package fr.uha.gabalier.view;
|
||||||
|
|
||||||
|
import fr.uha.gabalier.controller.ImageController;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ImageView extends View<List<Image>> {
|
||||||
|
|
||||||
|
public ImageView(List<Image> model) {
|
||||||
|
super(model);
|
||||||
|
this.setPreferredSize(new Dimension(Preview.VIEW_WIDTH, Preview.VIEW_HEIGHT));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void paintComponent(Graphics g) {
|
||||||
|
super.paintComponent(g);
|
||||||
|
final List<Image> model = this.getModel();
|
||||||
|
if (model == null) return;
|
||||||
|
if (model.size() == 0) return;
|
||||||
|
|
||||||
|
final int index = ((ImageController) this.getController()).getIndex();
|
||||||
|
g.drawImage(model.get(index), 10, 10, this);
|
||||||
|
}
|
||||||
|
}
|
@ -1,14 +1,85 @@
|
|||||||
package fr.uha.gabalier.view;
|
package fr.uha.gabalier.view;
|
||||||
|
|
||||||
|
import fr.uha.gabalier.controller.ImageController;
|
||||||
|
import fr.uha.gabalier.core.ImageLoader;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
|
import java.awt.event.InputEvent;
|
||||||
|
import java.awt.event.KeyEvent;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class Preview {
|
public class Preview extends JFrame {
|
||||||
|
|
||||||
|
static final int VIEW_WIDTH = 256;
|
||||||
|
static final int VIEW_HEIGHT = 128;
|
||||||
|
|
||||||
|
public static final String LEFT_COMMAND = "<";
|
||||||
|
public static final String RIGHT_COMMAND = ">";
|
||||||
|
private static final int ICON_WIDTH = 256;
|
||||||
|
|
||||||
private List<Image> model;
|
private List<Image> model;
|
||||||
private String status;
|
private ImageLoader loader;
|
||||||
|
private ImageView imageView;
|
||||||
|
|
||||||
|
// UI elements
|
||||||
|
private JMenuItem loadItem;
|
||||||
|
private JMenuItem cancelItem;
|
||||||
|
private JButton rightNavButton;
|
||||||
|
private JButton leftNavButton;
|
||||||
|
private final JTextField statusText;
|
||||||
|
|
||||||
|
public Preview() throws HeadlessException {
|
||||||
|
model = new ArrayList<>();
|
||||||
|
// UI elements
|
||||||
|
JMenuBar menuBar = new JMenuBar();
|
||||||
|
setJMenuBar(menuBar);
|
||||||
|
JMenu fileMenu = new JMenu("File");
|
||||||
|
menuBar.add(fileMenu);
|
||||||
|
|
||||||
|
loadItem = new JMenuItem("Load");
|
||||||
|
fileMenu.add(loadItem);
|
||||||
|
loadItem.addActionListener(actionEvent -> doLoad());
|
||||||
|
cancelItem = new JMenuItem("Cancel");
|
||||||
|
fileMenu.add(cancelItem);
|
||||||
|
cancelItem.addActionListener(actionEvent -> doCancel());
|
||||||
|
final JMenuItem exitItem = new JMenuItem("Exit");
|
||||||
|
exitItem.addActionListener(actionEvent -> doExit());
|
||||||
|
exitItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, InputEvent.CTRL_DOWN_MASK));
|
||||||
|
fileMenu.add(exitItem);
|
||||||
|
|
||||||
|
setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));
|
||||||
|
|
||||||
|
imageView = new ImageView(model);
|
||||||
|
final ImageController controller = new ImageController(model);
|
||||||
|
imageView.setController(controller);
|
||||||
|
controller.setView(imageView);
|
||||||
|
getContentPane().add(imageView);
|
||||||
|
|
||||||
|
final JPanel navPanel = new JPanel();
|
||||||
|
getContentPane().add(navPanel);
|
||||||
|
leftNavButton = new JButton(LEFT_COMMAND);
|
||||||
|
leftNavButton.addActionListener(controller);
|
||||||
|
navPanel.add(leftNavButton);
|
||||||
|
rightNavButton = new JButton(RIGHT_COMMAND);
|
||||||
|
rightNavButton.addActionListener(controller);
|
||||||
|
navPanel.add(rightNavButton);
|
||||||
|
|
||||||
|
final JPanel statusPanel = new JPanel();
|
||||||
|
getContentPane().add(statusPanel);
|
||||||
|
statusText = new JTextField("0000 images loaded");
|
||||||
|
statusPanel.add(new JLabel("status :"));
|
||||||
|
statusPanel.add(statusText);
|
||||||
|
|
||||||
|
pack();
|
||||||
|
setVisible(true);
|
||||||
|
}
|
||||||
|
|
||||||
public void setModel(List<Image> images) {
|
public void setModel(List<Image> images) {
|
||||||
this.model = images;
|
this.model.clear();
|
||||||
|
this.model.addAll(images);
|
||||||
|
((ImageController) imageView.getController()).resetIndex();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Image> getModel() {
|
public List<Image> getModel() {
|
||||||
@ -16,10 +87,44 @@ public class Preview {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setStatus(String status) {
|
public void setStatus(String status) {
|
||||||
this.status = status;
|
this.statusText.setText(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doLoad() {
|
||||||
|
final JFileChooser fc = new JFileChooser();
|
||||||
|
fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
|
||||||
|
final int ret = fc.showOpenDialog(this);
|
||||||
|
if (ret == JFileChooser.APPROVE_OPTION) {
|
||||||
|
loader = new ImageLoader(this, ICON_WIDTH, fc.getSelectedFile());
|
||||||
|
preLoad();
|
||||||
|
loader.execute();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doExit() {
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doCancel() {
|
||||||
|
loader.cancel(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void preLoad() {
|
||||||
|
loadItem.setEnabled(false);
|
||||||
|
cancelItem.setEnabled(true);
|
||||||
|
rightNavButton.setEnabled(false);
|
||||||
|
leftNavButton.setEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void postLoad() {
|
public void postLoad() {
|
||||||
|
loadItem.setEnabled(true);
|
||||||
|
cancelItem.setEnabled(false);
|
||||||
|
rightNavButton.setEnabled(true);
|
||||||
|
leftNavButton.setEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
EventQueue.invokeLater(Preview::new);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,27 @@
|
|||||||
package fr.uha.gabalier.view;
|
package fr.uha.gabalier.view;
|
||||||
|
|
||||||
public interface View {
|
import fr.uha.gabalier.controller.Controller;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
|
||||||
|
public class View<T> extends JPanel {
|
||||||
|
|
||||||
|
private final T model;
|
||||||
|
private Controller controller;
|
||||||
|
|
||||||
|
protected View(T model) {
|
||||||
|
this.model = model;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected T getModel() {
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Controller getController() {
|
||||||
|
return controller;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setController(Controller controller) {
|
||||||
|
this.controller = controller;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user