Honeycombs: Difference between revisions
Content added Content deleted
m (omit from|UNIX Shell) |
m (Added Java 8 version) |
||
Line 1,234: | Line 1,234: | ||
g.drawString(s, x, y); |
g.drawString(s, x, y); |
||
} |
} |
||
}</lang> |
|||
{{works with|Java|8+}} |
|||
<lang java>package graphics; |
|||
import java.awt.BasicStroke; |
|||
import java.awt.BorderLayout; |
|||
import java.awt.Container; |
|||
import java.awt.Color; |
|||
import java.awt.Dimension; |
|||
import java.awt.Font; |
|||
import java.awt.FontMetrics; |
|||
import java.awt.Graphics; |
|||
import java.awt.Graphics2D; |
|||
import java.awt.Polygon; |
|||
import java.awt.RenderingHints; |
|||
import java.awt.event.KeyEvent; |
|||
import java.awt.event.KeyListener; |
|||
import java.awt.event.MouseEvent; |
|||
import java.awt.event.MouseListener; |
|||
import javax.swing.JFrame; |
|||
import javax.swing.JPanel; |
|||
import static java.util.Arrays.parallelSetAll; |
|||
import static java.util.Arrays.stream; |
|||
import static java.util.stream.IntStream.range; |
|||
public class Honeycombs extends JFrame { |
|||
HoneycombsPanel panel; |
|||
public static void main(String[] args) { |
|||
JFrame f = new Honeycombs(); |
|||
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); |
|||
f.setVisible(true); |
|||
} |
|||
public Honeycombs() { |
|||
Container content = getContentPane(); |
|||
content.setLayout(new BorderLayout()); |
|||
panel = new HoneycombsPanel(); |
|||
content.add(panel, BorderLayout.CENTER); |
|||
setTitle("Honeycombs"); |
|||
setResizable(false); |
|||
pack(); |
|||
setLocationRelativeTo(null); |
|||
} |
|||
} |
|||
class HoneycombsPanel extends JPanel { |
|||
Hexagon[] comb; |
|||
@FunctionalInterface |
|||
private static interface MousePressed extends MouseListener { |
|||
public static MousePressed new_(MousePressed mousePressed) { |
|||
return mousePressed; |
|||
} |
|||
@Override |
|||
public default void mouseClicked(MouseEvent mouseEvent) {} |
|||
@Override |
|||
public default void mouseEntered(MouseEvent mouseEvent) {} |
|||
@Override |
|||
public default void mouseExited(MouseEvent mouseEvent) {} |
|||
@Override |
|||
public default void mouseReleased(MouseEvent mouseEvent) {} |
|||
} |
|||
@FunctionalInterface |
|||
private static interface KeyPressed extends KeyListener { |
|||
public static KeyPressed new_(KeyPressed keyPressed) { |
|||
return keyPressed; |
|||
} |
|||
@Override |
|||
public default void keyReleased(KeyEvent keyEvent) {} |
|||
@Override |
|||
public default void keyTyped(KeyEvent keyEvent) {} |
|||
} |
|||
public HoneycombsPanel() { |
|||
setPreferredSize(new Dimension(600, 500)); |
|||
setBackground(Color.white); |
|||
setFocusable(true); |
|||
addMouseListener(MousePressed.new_(e -> { |
|||
stream(comb) |
|||
.filter(hex -> hex.contains(e.getX(), e.getY())) |
|||
.findFirst() |
|||
.ifPresent(hex -> hex.setSelected()) |
|||
; |
|||
repaint(); |
|||
})); |
|||
addKeyListener(KeyPressed.new_(e -> { |
|||
stream(comb) |
|||
.filter(hex -> hex.letter == Character.toUpperCase(e.getKeyChar())) |
|||
.findFirst() |
|||
.ifPresent(hex -> hex.setSelected()) |
|||
; |
|||
repaint(); |
|||
})); |
|||
char[] letters = "LRDGITPFBVOKANUYCESM".toCharArray(); |
|||
comb = new Hexagon[20]; |
|||
int x1 = 150, y1 = 100, x2 = 225, y2 = 143, w = 150, h = 87; |
|||
parallelSetAll(comb, i -> { |
|||
int x, y; |
|||
if (i < 12) { |
|||
x = x1 + (i % 3) * w; |
|||
y = y1 + (i / 3) * h; |
|||
} else { |
|||
x = x2 + (i % 2) * w; |
|||
y = y2 + ((i - 12) / 2) * h; |
|||
} |
|||
return new Hexagon(x, y, w / 3, letters[i]); |
|||
}); |
|||
requestFocus(); |
|||
} |
|||
@Override |
|||
public void paintComponent(Graphics gg) { |
|||
super.paintComponent(gg); |
|||
Graphics2D g = (Graphics2D) gg; |
|||
g.setRenderingHint( |
|||
RenderingHints.KEY_ANTIALIASING, |
|||
RenderingHints.VALUE_ANTIALIAS_ON |
|||
); |
|||
g.setFont(new Font("SansSerif", Font.BOLD, 30)); |
|||
g.setStroke(new BasicStroke(3)); |
|||
stream(comb) |
|||
.forEach(hex -> hex.draw(g)) |
|||
; |
|||
} |
|||
} |
|||
class Hexagon extends Polygon { |
|||
final Color baseColor = Color.yellow; |
|||
final Color selectedColor = Color.magenta; |
|||
final char letter; |
|||
private boolean hasBeenSelected; |
|||
Hexagon(int x, int y, int halfWidth, char c) { |
|||
letter = c; |
|||
range(0, 6) |
|||
.forEach(i -> |
|||
addPoint((int) (x + halfWidth * Math.cos(i * Math.PI / 3)), |
|||
(int) (y + halfWidth * Math.sin(i * Math.PI / 3))) |
|||
) |
|||
; |
|||
getBounds(); |
|||
} |
|||
void setSelected() { |
|||
hasBeenSelected = true; |
|||
} |
|||
void draw(Graphics2D g) { |
|||
g.setColor(hasBeenSelected ? selectedColor : baseColor); |
|||
g.fillPolygon(this); |
|||
g.setColor(Color.black); |
|||
g.drawPolygon(this); |
|||
g.setColor(hasBeenSelected ? Color.black : Color.red); |
|||
drawCenteredString(g, String.valueOf(letter)); |
|||
} |
|||
void drawCenteredString(Graphics2D g, String s) { |
|||
FontMetrics fm = g.getFontMetrics(); |
|||
int asc = fm.getAscent(); |
|||
int dec = fm.getDescent(); |
|||
int x = bounds.x + (bounds.width - fm.stringWidth(s)) / 2; |
|||
int y = bounds.y + (asc + (bounds.height - (asc + dec)) / 2); |
|||
g.drawString(s, x, y); |
|||
} |
|||
}</lang> |
}</lang> |
||