Add various gui samples
This commit is contained in:
15
gui/pom.xml
Normal file
15
gui/pom.xml
Normal file
@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>java-cookbook</artifactId>
|
||||
<groupId>fr.gasser</groupId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>gui</artifactId>
|
||||
|
||||
|
||||
</project>
|
84
gui/src/main/java/fr/gasser/gui/Mandelbrot.java
Normal file
84
gui/src/main/java/fr/gasser/gui/Mandelbrot.java
Normal file
@ -0,0 +1,84 @@
|
||||
package fr.gasser.gui;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
public class Mandelbrot extends JFrame {
|
||||
|
||||
private static final int imgSize = 256;
|
||||
|
||||
private final BufferedImage img;
|
||||
|
||||
private Mandelbrot(double xc, double yc, double size) throws HeadlessException {
|
||||
super("fr.gasser.gui.Mandelbrot set");
|
||||
setDefaultCloseOperation(EXIT_ON_CLOSE);
|
||||
int max = 255; // maximum number of iterations
|
||||
|
||||
setPreferredSize(new Dimension(imgSize, imgSize));
|
||||
setMinimumSize(getPreferredSize());
|
||||
setMaximumSize(getPreferredSize());
|
||||
setResizable(false);
|
||||
|
||||
|
||||
img = new BufferedImage(imgSize, imgSize, BufferedImage.TYPE_INT_RGB);
|
||||
for (int i = 0; i < imgSize; i++) {
|
||||
for (int j = 0; j < imgSize; j++) {
|
||||
double x0 = xc - size/2 + size*i/imgSize;
|
||||
double y0 = yc - size/2 + size*j/imgSize;
|
||||
Complex z0 = new Complex(x0, y0);
|
||||
int gray = max - mand(z0, max);
|
||||
Color color = new Color(gray, gray, gray);
|
||||
img.setRGB(i, imgSize-1-j, color.getRGB());
|
||||
}
|
||||
}
|
||||
|
||||
setVisible(true);
|
||||
}
|
||||
|
||||
// return number of iterations to check if c = a + ib is in fr.gasser.gui.Mandelbrot set
|
||||
private int mand(Complex z0, int max) {
|
||||
Complex z = z0;
|
||||
for (int t = 0; t < max; t++) {
|
||||
if (z.abs() > 2.0) return t;
|
||||
z = z.times(z).plus(z0);
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint(Graphics g) {
|
||||
g.drawImage(img, 0, 0, this);
|
||||
}
|
||||
|
||||
private static class Complex {
|
||||
|
||||
private final double re;
|
||||
private final double im;
|
||||
|
||||
Complex(double real, double imaginary) {
|
||||
this.re = real;
|
||||
this.im = imaginary;
|
||||
}
|
||||
|
||||
double abs() {
|
||||
return re * re + im * im;
|
||||
}
|
||||
|
||||
Complex times(Complex b) {
|
||||
Complex a = this;
|
||||
double real = a.re * b.re - a.im * b.im;
|
||||
double imag = a.re * b.im + a.im * b.re;
|
||||
return new Complex(real, imag);
|
||||
}
|
||||
|
||||
Complex plus(Complex other) {
|
||||
return new Complex(this.re + other.re, this.im + other.im);
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
EventQueue.invokeLater(() -> new Mandelbrot(-1, -0.25, 0.25));
|
||||
}
|
||||
}
|
141
gui/src/main/java/fr/gasser/gui/editor/App.java
Normal file
141
gui/src/main/java/fr/gasser/gui/editor/App.java
Normal file
@ -0,0 +1,141 @@
|
||||
package fr.gasser.gui.editor;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.text.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ItemEvent;
|
||||
|
||||
public class App extends JFrame {
|
||||
|
||||
private final static Logger LOGGER = LoggerFactory.getLogger(App.class);
|
||||
private static final Font DEFAULT_FONT = new Font("Arial", Font.PLAIN, 14);
|
||||
private static final Color DEFAULT_COLOR = Color.BLACK;
|
||||
private static final String LOREM_IPSUM = "Quisque eget mattis nulla. Praesent efficitur fermentum neque quis fringilla. Quisque laoreet eros maximus nibh eleifend, eu faucibus tortor egestas. Proin finibus eu tortor eget dictum. Interdum et malesuada fames ac ante ipsum primis in faucibus. Nullam quis nisi sit amet magna ullamcorper sollicitudin. Curabitur vel pellentesque lorem, in tristique dolor.";
|
||||
|
||||
private JTextPane editArea;
|
||||
private JButton colorButton;
|
||||
|
||||
private App() throws HeadlessException {
|
||||
setDefaultCloseOperation(EXIT_ON_CLOSE);
|
||||
try {
|
||||
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
|
||||
} catch (Exception e) {
|
||||
LOGGER.warn(e.getMessage());
|
||||
}
|
||||
initComponents();
|
||||
pack();
|
||||
setVisible(true);
|
||||
}
|
||||
|
||||
private void initComponents() {
|
||||
setLayout(new BorderLayout());
|
||||
final JPanel topPane = new JPanel();
|
||||
topPane.setLayout(new BorderLayout());
|
||||
final JPanel bottomPane = new JPanel();
|
||||
|
||||
editArea = new JTextPane();
|
||||
editArea.setText(LOREM_IPSUM);
|
||||
editArea.setFont(DEFAULT_FONT);
|
||||
final JScrollPane textScrollPane = new JScrollPane(editArea);
|
||||
textScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
|
||||
textScrollPane.setPreferredSize(new Dimension(144, 256));
|
||||
topPane.add(textScrollPane);
|
||||
|
||||
final FontChooser fontChooser = new FontChooser();
|
||||
fontChooser.addItemListener(this::doChangeFont);
|
||||
fontChooser.setSelectedItem(fontChooser.get(DEFAULT_FONT));
|
||||
bottomPane.add(fontChooser);
|
||||
|
||||
final JComboBox<Integer> fontSizeChooser = new JComboBox<>();
|
||||
for (int i=5; i < 200; i++) fontSizeChooser.addItem(i);
|
||||
fontSizeChooser.addItemListener(this::doChangeFontSize);
|
||||
fontSizeChooser.setSelectedItem(DEFAULT_FONT.getSize());
|
||||
bottomPane.add(fontSizeChooser);
|
||||
|
||||
colorButton = new JButton();
|
||||
colorButton.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
colorButton.setVerticalAlignment(SwingConstants.CENTER);
|
||||
colorButton.setIcon(new SquareIcon(30, DEFAULT_COLOR));
|
||||
colorButton.addActionListener(evt -> doChangeColor());
|
||||
bottomPane.add(colorButton);
|
||||
|
||||
final JButton boldButton = new JButton(new StyledEditorKit.BoldAction());
|
||||
boldButton.setText("B");
|
||||
bottomPane.add(boldButton);
|
||||
|
||||
final JButton italicButton = new JButton(new StyledEditorKit.ItalicAction());
|
||||
italicButton.setText("I");
|
||||
bottomPane.add(italicButton);
|
||||
|
||||
final JButton underlineButton = new JButton(new StyledEditorKit.UnderlineAction());
|
||||
underlineButton.setText("U");
|
||||
bottomPane.add(underlineButton);
|
||||
|
||||
final Container container = getContentPane();
|
||||
container.add(topPane, BorderLayout.NORTH);
|
||||
container.add(bottomPane, BorderLayout.SOUTH);
|
||||
}
|
||||
|
||||
private void doChangeColor() {
|
||||
final Color c = JColorChooser.showDialog(this, "Choose a color", Color.BLACK);
|
||||
SimpleAttributeSet attr = new SimpleAttributeSet(getSelectedElement().getAttributes().copyAttributes());
|
||||
StyleConstants.setForeground(attr, c);
|
||||
editArea.setCharacterAttributes(attr, true);
|
||||
colorButton.setIcon(new SquareIcon(30, c));
|
||||
|
||||
}
|
||||
|
||||
private void doChangeFont(ItemEvent evt) {
|
||||
final Font f = (Font) evt.getItem();
|
||||
|
||||
SimpleAttributeSet attr = new SimpleAttributeSet(getSelectedElement().getAttributes().copyAttributes());
|
||||
StyleConstants.setFontFamily(attr, f.getName());
|
||||
editArea.setCharacterAttributes(attr, true);
|
||||
}
|
||||
|
||||
private void doChangeFontSize(ItemEvent evt) {
|
||||
SimpleAttributeSet attr = new SimpleAttributeSet(getSelectedElement().getAttributes().copyAttributes());
|
||||
StyleConstants.setFontSize(attr, (int) evt.getItem());
|
||||
editArea.setCharacterAttributes(attr, true);
|
||||
}
|
||||
|
||||
private Element getSelectedElement() {
|
||||
final StyledDocument doc = (StyledDocument) editArea.getDocument();
|
||||
return doc.getCharacterElement(editArea.getSelectionStart());
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
EventQueue.invokeLater(App::new);
|
||||
}
|
||||
|
||||
private static class SquareIcon implements Icon {
|
||||
private final int size;
|
||||
private final Color color;
|
||||
|
||||
SquareIcon(int size, Color color) {
|
||||
this.size = size;
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintIcon(Component component, Graphics graphics, int i, int i1) {
|
||||
final Point center = new Point(component.getWidth()/4, component.getHeight()/4);
|
||||
final Graphics2D g2d = (Graphics2D) graphics;
|
||||
g2d.setColor(color);
|
||||
g2d.fillRect(center.x, center.y, size, size);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIconWidth() {
|
||||
return size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIconHeight() {
|
||||
return size;
|
||||
}
|
||||
}
|
||||
}
|
56
gui/src/main/java/fr/gasser/gui/editor/FontChooser.java
Normal file
56
gui/src/main/java/fr/gasser/gui/editor/FontChooser.java
Normal file
@ -0,0 +1,56 @@
|
||||
package fr.gasser.gui.editor;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
|
||||
class FontChooser extends JComboBox<Font> {
|
||||
|
||||
FontChooser() {
|
||||
|
||||
final Font[] fonts = GraphicsEnvironment
|
||||
.getLocalGraphicsEnvironment()
|
||||
.getAllFonts();
|
||||
|
||||
Arrays.sort(fonts, Comparator.comparing(Font::getName));
|
||||
|
||||
for (Font font : fonts) {
|
||||
if (font.canDisplayUpTo(font.getName()) == -1) {
|
||||
addItem(font);
|
||||
}
|
||||
}
|
||||
|
||||
setRenderer(new FontCellRenderer());
|
||||
}
|
||||
|
||||
Font get(Font font) {
|
||||
for (int i = 0; i < getModel().getSize(); i++) {
|
||||
final Font f = getItemAt(i);
|
||||
if (f.getName().equals(font.getName())) return f;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static class FontCellRenderer
|
||||
implements ListCellRenderer<Font> {
|
||||
|
||||
DefaultListCellRenderer renderer = new DefaultListCellRenderer();
|
||||
|
||||
public Component getListCellRendererComponent(
|
||||
JList<? extends Font> list, Font font, int index,
|
||||
boolean isSelected, boolean cellHasFocus) {
|
||||
|
||||
final Component result = renderer.getListCellRendererComponent(
|
||||
list, font.getName(), index, isSelected, cellHasFocus);
|
||||
|
||||
setFontPreserveSize(result, font);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
private static void setFontPreserveSize(final Component comp, Font font) {
|
||||
final float size = comp.getFont().getSize();
|
||||
comp.setFont(font.deriveFont(size));
|
||||
}
|
||||
}
|
61
gui/src/main/java/fr/gasser/gui/test/Main.java
Normal file
61
gui/src/main/java/fr/gasser/gui/test/Main.java
Normal file
@ -0,0 +1,61 @@
|
||||
package fr.gasser.gui.test;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
||||
public class Main extends JFrame {
|
||||
|
||||
private static final String TEXT = "你好,世界";
|
||||
private final Model model;
|
||||
private final View view;
|
||||
|
||||
private Main() {
|
||||
super("Demo");
|
||||
setDefaultCloseOperation(EXIT_ON_CLOSE);
|
||||
|
||||
// Initialize model
|
||||
model = new Model(
|
||||
new Font("Fira Sans", Font.PLAIN, 50),
|
||||
new Point(50, 50),
|
||||
Color.RED, TEXT
|
||||
);
|
||||
|
||||
view = new View(model);
|
||||
getContentPane().add(view);
|
||||
|
||||
setJMenuBar(createMenuBar());
|
||||
|
||||
pack();
|
||||
setVisible(true);
|
||||
}
|
||||
|
||||
private JMenuBar createMenuBar() {
|
||||
final JMenuBar menuBar = new JMenuBar();
|
||||
final JButton bold = new JButton("B");
|
||||
bold.addActionListener(evt -> {
|
||||
model.setBold(!model.getFont().isBold());
|
||||
view.repaint();
|
||||
});
|
||||
menuBar.add(bold);
|
||||
|
||||
final JButton italic = new JButton("I");
|
||||
italic.addActionListener(evt -> {
|
||||
model.setItalic(!model.getFont().isItalic());
|
||||
view.repaint();
|
||||
});
|
||||
menuBar.add(italic);
|
||||
|
||||
final JButton antiAlias = new JButton("AA");
|
||||
antiAlias.addActionListener(evt -> {
|
||||
model.setAntialias(!model.isAntialiased());
|
||||
view.repaint();
|
||||
});
|
||||
menuBar.add(antiAlias);
|
||||
|
||||
return menuBar;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
EventQueue.invokeLater(Main::new);
|
||||
}
|
||||
}
|
51
gui/src/main/java/fr/gasser/gui/test/Model.java
Normal file
51
gui/src/main/java/fr/gasser/gui/test/Model.java
Normal file
@ -0,0 +1,51 @@
|
||||
package fr.gasser.gui.test;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
class Model {
|
||||
|
||||
private Font font;
|
||||
private Point pos;
|
||||
private Paint paint;
|
||||
private String text;
|
||||
private boolean antialiased = true;
|
||||
|
||||
Model(Font font, Point pos, Paint paint, String text) {
|
||||
this.font = font;
|
||||
this.pos = pos;
|
||||
this.paint = paint;
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
Font getFont() {
|
||||
return font;
|
||||
}
|
||||
|
||||
Point getPos() {
|
||||
return pos;
|
||||
}
|
||||
|
||||
Paint getPaint() {
|
||||
return paint;
|
||||
}
|
||||
|
||||
String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
boolean isAntialiased() {
|
||||
return antialiased;
|
||||
}
|
||||
|
||||
void setAntialias(boolean b) {
|
||||
this.antialiased = b;
|
||||
}
|
||||
|
||||
void setBold(boolean bold) {
|
||||
this.font = font.deriveFont(bold ? Font.BOLD : Font.PLAIN);
|
||||
}
|
||||
|
||||
void setItalic(boolean italic) {
|
||||
this.font = font.deriveFont(italic ? Font.ITALIC : Font.PLAIN);
|
||||
}
|
||||
}
|
43
gui/src/main/java/fr/gasser/gui/test/View.java
Normal file
43
gui/src/main/java/fr/gasser/gui/test/View.java
Normal file
@ -0,0 +1,43 @@
|
||||
package fr.gasser.gui.test;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.font.TextAttribute;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Map;
|
||||
|
||||
public class View extends JPanel {
|
||||
|
||||
private Model model;
|
||||
View(Model model) {
|
||||
this.model = model;
|
||||
setPreferredSize(getPreferredSize());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getPreferredSize() {
|
||||
return new Dimension(640, 360);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintComponent(Graphics g) {
|
||||
super.paintComponent(g);
|
||||
|
||||
Graphics2D g2d = (Graphics2D) g;
|
||||
g2d.setRenderingHint(
|
||||
RenderingHints.KEY_TEXT_ANTIALIASING,
|
||||
model.isAntialiased() ?
|
||||
RenderingHints.VALUE_TEXT_ANTIALIAS_ON :
|
||||
RenderingHints.VALUE_TEXT_ANTIALIAS_OFF
|
||||
);
|
||||
|
||||
g2d.setFont(model.getFont());
|
||||
g2d.setPaint(model.getPaint());
|
||||
|
||||
g2d.drawString(model.getText(), model.getPos().x, model.getPos().y);
|
||||
}
|
||||
|
||||
public void setModel(Model model) {
|
||||
this.model = model;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user