Commit | Line | Data |
---|---|---|
a3b510ab NR |
1 | package com.googlecode.lanterna.terminal.swing; |
2 | ||
3 | import com.googlecode.lanterna.TerminalSize; | |
4 | import com.googlecode.lanterna.TextCharacter; | |
5 | ||
6 | import javax.swing.*; | |
7 | import java.awt.*; | |
8 | import java.awt.event.HierarchyEvent; | |
9 | import java.awt.event.HierarchyListener; | |
10 | import java.awt.event.MouseAdapter; | |
11 | import java.awt.event.MouseEvent; | |
12 | import java.io.IOException; | |
13 | import java.util.Collections; | |
14 | ||
15 | /** | |
16 | * Concrete implementation of {@link GraphicalTerminalImplementation} that adapts it to Swing | |
17 | */ | |
18 | class SwingTerminalImplementation extends GraphicalTerminalImplementation { | |
19 | ||
20 | private final JComponent component; | |
21 | private final SwingTerminalFontConfiguration fontConfiguration; | |
22 | ||
23 | /** | |
24 | * Creates a new {@code SwingTerminalImplementation} | |
25 | * @param component JComponent that is the Swing terminal surface | |
26 | * @param fontConfiguration Font configuration to use | |
27 | * @param initialTerminalSize Initial size of the terminal | |
28 | * @param deviceConfiguration Device configuration | |
29 | * @param colorConfiguration Color configuration | |
30 | * @param scrollController Controller to be used when inspecting scroll status | |
31 | */ | |
32 | SwingTerminalImplementation( | |
33 | JComponent component, | |
34 | SwingTerminalFontConfiguration fontConfiguration, | |
35 | TerminalSize initialTerminalSize, | |
36 | TerminalEmulatorDeviceConfiguration deviceConfiguration, | |
37 | TerminalEmulatorColorConfiguration colorConfiguration, | |
38 | TerminalScrollController scrollController) { | |
39 | ||
40 | super(initialTerminalSize, deviceConfiguration, colorConfiguration, scrollController); | |
41 | this.component = component; | |
42 | this.fontConfiguration = fontConfiguration; | |
43 | ||
44 | //Prevent us from shrinking beyond one character | |
45 | component.setMinimumSize(new Dimension(fontConfiguration.getFontWidth(), fontConfiguration.getFontHeight())); | |
46 | ||
47 | //noinspection unchecked | |
48 | component.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, Collections.<AWTKeyStroke>emptySet()); | |
49 | //noinspection unchecked | |
50 | component.setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, Collections.<AWTKeyStroke>emptySet()); | |
51 | ||
52 | //Make sure the component is double-buffered to prevent flickering | |
53 | component.setDoubleBuffered(true); | |
54 | ||
55 | component.addKeyListener(new TerminalInputListener()); | |
56 | component.addMouseListener(new MouseAdapter() { | |
57 | @Override | |
58 | public void mouseClicked(MouseEvent e) { | |
59 | SwingTerminalImplementation.this.component.requestFocusInWindow(); | |
60 | } | |
61 | }); | |
62 | component.addHierarchyListener(new HierarchyListener() { | |
63 | @Override | |
64 | public void hierarchyChanged(HierarchyEvent e) { | |
65 | if(e.getChangeFlags() == HierarchyEvent.DISPLAYABILITY_CHANGED) { | |
66 | if(e.getChanged().isDisplayable()) { | |
67 | startBlinkTimer(); | |
68 | } | |
69 | else { | |
70 | stopBlinkTimer(); | |
71 | } | |
72 | } | |
73 | } | |
74 | }); | |
75 | } | |
76 | ||
77 | ||
78 | /** | |
79 | * Returns the current font configuration. Note that it is immutable and cannot be changed. | |
80 | * @return This SwingTerminal's current font configuration | |
81 | */ | |
82 | public SwingTerminalFontConfiguration getFontConfiguration() { | |
83 | return fontConfiguration; | |
84 | } | |
85 | ||
86 | @Override | |
87 | protected int getFontHeight() { | |
88 | return fontConfiguration.getFontHeight(); | |
89 | } | |
90 | ||
91 | @Override | |
92 | protected int getFontWidth() { | |
93 | return fontConfiguration.getFontWidth(); | |
94 | } | |
95 | ||
96 | @Override | |
97 | protected int getHeight() { | |
98 | return component.getHeight(); | |
99 | } | |
100 | ||
101 | @Override | |
102 | protected int getWidth() { | |
103 | return component.getWidth(); | |
104 | } | |
105 | ||
106 | @Override | |
107 | protected Font getFontForCharacter(TextCharacter character) { | |
108 | return fontConfiguration.getFontForCharacter(character); | |
109 | } | |
110 | ||
111 | @Override | |
112 | protected boolean isTextAntiAliased() { | |
113 | return fontConfiguration.isAntiAliased(); | |
114 | } | |
115 | ||
116 | @Override | |
117 | protected void repaint() { | |
118 | if(SwingUtilities.isEventDispatchThread()) { | |
119 | component.repaint(); | |
120 | } | |
121 | else { | |
122 | SwingUtilities.invokeLater(new Runnable() { | |
123 | @Override | |
124 | public void run() { | |
125 | component.repaint(); | |
126 | } | |
127 | }); | |
128 | } | |
129 | } | |
130 | ||
131 | @Override | |
132 | public com.googlecode.lanterna.input.KeyStroke readInput() throws IOException { | |
133 | if(SwingUtilities.isEventDispatchThread()) { | |
134 | throw new UnsupportedOperationException("Cannot call SwingTerminal.readInput() on the AWT thread"); | |
135 | } | |
136 | return super.readInput(); | |
137 | } | |
138 | } |