Add various gui samples

This commit is contained in:
Thibaud Gasser 2018-10-24 00:18:20 +02:00
parent 5b25596359
commit 8a8fa12b48
15 changed files with 690 additions and 0 deletions

View File

@ -0,0 +1,44 @@
package asyncservice;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
class ExampleService {
private static final Logger LOGGER = LoggerFactory.getLogger(Main.class);
String work() {
sleep(7000, TimeUnit.MILLISECONDS); /* Pretend to be busy... */
char[] str = new char[5];
ThreadLocalRandom current = ThreadLocalRandom.current();
for (int idx = 0; idx < str.length; ++idx)
str[idx] = (char) ('A' + current.nextInt(26));
String msg = new String(str);
log("Generated message: " + msg);
return msg;
}
private void sleep(long average, TimeUnit unit) {
String name = Thread.currentThread().getName();
long timeout = Math.min(exponential(average), Math.multiplyExact(10, average));
log("{} sleeping {} {}...", name, timeout, unit);
try {
unit.sleep(timeout);
log(name + " awoke.");
} catch (InterruptedException abort) {
Thread.currentThread().interrupt();
log(name + " interrupted.");
}
}
private long exponential(long avg) {
return (long) (avg * -Math.log(1 - ThreadLocalRandom.current().nextDouble()));
}
private void log(String s, Object... o) {
LOGGER.info(s, o);
}
}

View File

@ -0,0 +1,49 @@
package asyncservice;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.concurrent.*;
public class Main {
private static final Logger LOGGER = LoggerFactory.getLogger(Main.class);
private static <T> Callable<T> lazyval(T val, long timeout) {
return () -> {
Thread.sleep(1000);
log("Task completed with : " + val);
return val;
};
}
public static void main(String[] args) throws InterruptedException {
ExecutorService executor = Executors.newFixedThreadPool(4);
final Future<Integer> asyncRes = executor.submit(lazyval(1, 100L));
final Future<String> asyncRes1 = executor.submit(lazyval("Hello", 20L));
final Future<String> asyncRes2 = executor.submit(lazyval("World", 100L));
Thread.sleep(15000);
log("End of executor example.");
executor.shutdown();
getTaskNotificationWithoutBlocking();
}
private static void getTaskNotificationWithoutBlocking() throws InterruptedException {
ExampleService svc = new ExampleService();
CompletableFuture<String> future = CompletableFuture.supplyAsync(svc::work);
Main listener = new Main();
future.thenAccept(listener::notify);
Thread.sleep(10000);
log("Exciting main...");
}
private void notify(String s) {
log("Received message ", s);
}
private static void log(String s, Object... o) {
LOGGER.info(s, o);
}
}

View File

@ -0,0 +1,24 @@
package threadexamples;
public class BasicThreadExample extends Thread {
private static int cpt = 0;
@Override
public void run() {
int tmp = cpt;
for (int i = 0; i < 1000000; i++);
tmp++;
cpt = tmp;
}
public static void main(String[] args) throws InterruptedException {
Thread thread1 = new BasicThreadExample();
Thread thread2 = new BasicThreadExample();
thread1.start();
thread2.start();
thread1.join();
thread2.join();
System.out.println("Compteur : " + cpt);
}
}

View File

@ -0,0 +1,40 @@
package threadexamples.producerconsumer;
import org.slf4j.LoggerFactory;
import java.util.concurrent.*;
public class App {
public static void main(String[] args) {
BlockingQueue<Item> itemQueue = new LinkedBlockingQueue<>(5);
ExecutorService executorService = Executors.newFixedThreadPool(5);
for (int i = 0; i < 2; i++) {
final Producer producer = new Producer("Producer_" + i, itemQueue);
executorService.submit(() -> {
while (true) {
producer.produce();
}
});
}
for (int i = 0; i < 3; i++) {
final Consumer consumer = new Consumer("Consumer_" + i, itemQueue);
executorService.submit(() -> {
while(true) {
consumer.consume();
}
});
}
executorService.shutdown();
try {
executorService.awaitTermination(10, TimeUnit.SECONDS);
executorService.shutdownNow();
} catch (InterruptedException e) {
LoggerFactory.getLogger(App.class).error("Error waiting for ExecutorService shutdown");
}
}
}

View File

@ -0,0 +1,25 @@
package threadexamples.producerconsumer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.concurrent.BlockingQueue;
public class Consumer {
private static final Logger LOGGER = LoggerFactory.getLogger(Consumer.class);
private BlockingQueue<Item> itemQueue;
private String name;
private int itemId;
public Consumer(String name, BlockingQueue<Item> itemQueue) {
this.itemQueue = itemQueue;
this.name = name;
}
public void consume() throws InterruptedException {
final Item item = itemQueue.take();
LOGGER.info("Consumer [{}] consume item [{}] produced by [{}]", name, item.getId(), item.getProducer());
}
}

View File

@ -0,0 +1,21 @@
package threadexamples.producerconsumer;
public class Item {
private String producer;
private int id;
public Item(String producer, int id) {
this.producer = producer;
this.id = id;
}
public String getProducer() {
return producer;
}
public int getId() {
return id;
}
}

View File

@ -0,0 +1,21 @@
package threadexamples.producerconsumer;
import java.util.Random;
import java.util.concurrent.BlockingQueue;
public class Producer {
private BlockingQueue<Item> itemQueue;
private String name;
private int itemId;
public Producer(String name, BlockingQueue itemQueue) {
this.itemQueue = itemQueue;
this.name = name;
}
public void produce() throws InterruptedException {
itemQueue.put(new Item(name, itemId++));
Thread.sleep(new Random().nextInt(2000));
}
}

15
gui/pom.xml Normal file
View 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>

View 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));
}
}

View 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;
}
}
}

View 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));
}
}

View 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);
}
}

View 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);
}
}

View 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;
}
}

15
pom.xml
View File

@ -8,6 +8,7 @@
<modules>
<module>reflection</module>
<module>gui</module>
</modules>
<properties>
@ -16,4 +17,18 @@
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>RELEASE</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>RELEASE</version>
</dependency>
</dependencies>
</project>