 |
Crossfire JXClient, Trunk
|
Go to the documentation of this file.
23 package com.realtime.crossfire.jxclient.gui.misc;
43 import java.awt.Color;
44 import java.awt.Component;
45 import java.awt.Container;
46 import java.awt.Dimension;
47 import java.awt.DisplayMode;
48 import java.awt.Frame;
49 import java.awt.Graphics;
50 import java.awt.GraphicsConfiguration;
51 import java.awt.GraphicsDevice;
52 import java.awt.GraphicsEnvironment;
53 import java.awt.Insets;
54 import java.awt.Point;
55 import java.awt.Rectangle;
56 import java.awt.Toolkit;
57 import java.awt.Window;
58 import java.awt.event.ComponentEvent;
59 import java.awt.event.ComponentListener;
60 import java.awt.event.KeyEvent;
61 import java.awt.event.MouseEvent;
62 import java.awt.event.MouseWheelEvent;
63 import java.awt.event.MouseWheelListener;
64 import java.awt.image.BufferStrategy;
65 import java.io.IOException;
66 import java.io.Writer;
67 import java.time.LocalDateTime;
68 import java.time.format.DateTimeFormatter;
69 import java.util.Collection;
70 import java.util.Iterator;
71 import java.util.List;
72 import java.util.ListIterator;
73 import java.util.Locale;
74 import java.util.concurrent.CopyOnWriteArrayList;
75 import javax.swing.JFrame;
76 import javax.swing.JLayeredPane;
77 import javax.swing.JViewport;
78 import javax.swing.RootPaneContainer;
79 import javax.swing.event.MouseInputListener;
80 import org.jetbrains.annotations.NotNull;
81 import org.jetbrains.annotations.Nullable;
120 private static final long serialVersionUID = 1L;
123 public void paint(@NotNull
final Graphics g) {
170 private final Rectangle
maximumWindowBounds = GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds();
179 public void mouseClicked(
final MouseEvent e) {
184 public void mousePressed(
final MouseEvent e) {
189 public void mouseReleased(
final MouseEvent e) {
194 public void mouseEntered(
final MouseEvent e) {
199 public void mouseExited(
final MouseEvent e) {
204 public void mouseDragged(
final MouseEvent e) {
209 public void mouseMoved(
final MouseEvent e) {
222 public void mouseWheelMoved(
final MouseWheelEvent e) {
252 private final List<Gui>
openDialogs =
new CopyOnWriteArrayList<>();
271 private final Collection<GUIMap>
maps =
new CopyOnWriteArrayList<>();
278 private final Collection<GUIFloorList>
floorLists =
new CopyOnWriteArrayList<>();
316 private static final DateTimeFormatter
FORMATTER = DateTimeFormatter.ofPattern(
"yyyy-MM-dd HH:mm:ss,SSS ", Locale.ENGLISH);
325 public void componentResized(
final ComponentEvent e) {
326 final RootPaneContainer tmpFrame =
frame;
327 assert tmpFrame !=
null;
328 final int width = tmpFrame.getContentPane().getWidth();
329 final int height = tmpFrame.getContentPane().getHeight();
335 public void componentMoved(
final ComponentEvent e) {
340 public void componentShown(
final ComponentEvent e) {
345 public void componentHidden(
final ComponentEvent e) {
376 debugScreenWrite(
"setFullScreenMode: resolution="+(resolution ==
null ?
"default" : resolution));
387 final Dimension dimension;
388 if (resolution ==
null) {
389 dimension =
new Dimension(currentDisplayMode.getWidth(), currentDisplayMode.getHeight());
390 debugScreenWrite(
"setFullScreenMode: full-screen requested, dimension="+dimension+
" [using current display resolution]");
392 dimension =
new Dimension(resolution.getWidth(), resolution.getHeight());
393 debugScreenWrite(
"setFullScreenMode: full-screen requested, dimension="+dimension+
" [using user-specified resolution]");
395 frame.setPreferredSize(dimension);
396 frame.setResizable(
false);
397 frame.setUndecorated(
true);
408 if (resolution ==
null || resolution.equalsDisplayMode(currentDisplayMode)) {
409 debugScreenWrite(
"setFullScreenMode: requested resolution matches screen resolution");
417 final DisplayMode newDisplayMode =
new DisplayMode(resolution.getWidth(), resolution.getHeight(), DisplayMode.BIT_DEPTH_MULTI, DisplayMode.REFRESH_RATE_UNKNOWN);
420 }
catch (
final IllegalArgumentException ex) {
421 debugScreenWrite(
"setFullScreenMode: setting screen resolution failed: "+ex.getMessage());
430 if (this.frame !=
null) {
449 debugScreenWrite(
"setWindowMode: resolution="+(resolution ==
null ?
"default" : resolution)+
", minResolution="+minResolution+
", fixedSize="+fixedSize);
461 frame.setUndecorated(
false);
462 frame.setResizable(!fixedSize);
464 final Dimension dimension;
466 if (resolution ==
null) {
467 dimension =
new Dimension(currentDisplayMode.getWidth(), currentDisplayMode.getHeight());
469 dimension = resolution.asDimension();
471 final int x = centerPoint.x-dimension.width/2;
472 final int y = centerPoint.y-dimension.height/2;
474 frame.setLocation(x, y);
476 frame.setVisible(
true);
477 final Insets frameInsets =
frame.getInsets();
478 debugScreenWrite(
"setResolutionPre: frame insets: top="+frameInsets.top+
", bottom="+frameInsets.bottom+
", left="+frameInsets.left+
", right="+frameInsets.right);
481 debugScreenWrite(
"setResolutionPre: maximum window dimension: "+maxDimension.width+
"x"+maxDimension.height);
482 if (dimension.width > maxDimension.width || dimension.height > maxDimension.height) {
484 if (resolution ==
null) {
485 final int tmpWidth = dimension.width;
486 final int tmpHeight = dimension.height;
487 dimension.width = Math.max(minResolution.getWidth()+frameInsets.left+frameInsets.right, maxDimension.width);
488 dimension.height = Math.max(minResolution.getHeight()+frameInsets.top+frameInsets.bottom, maxDimension.height);
489 debugScreenWrite(
"setResolutionPre: window size "+tmpWidth+
"x"+tmpHeight+
" exceeds maximum allowed size "+maxDimension.width+
"x"+maxDimension.height+
", reducing to "+dimension.width+
"x"+dimension.height);
491 debugScreenWrite(
"setResolutionPre: window size "+dimension.width+
"x"+dimension.height+
" exceeds maximum allowed size "+maxDimension.width+
"x"+maxDimension.height+
", ignoring");
497 frame.setPreferredSize(dimension);
498 frame.setSize(dimension);
501 final int x2 = centerPoint.x-dimension.width/2-frameInsets.left;
502 final int y2 = centerPoint.y-dimension.height/2-frameInsets.top;
503 debugScreenWrite(
"setResolutionPre: moving window to ("+frameInsets.left+
"+"+dimension.width+
"+"+frameInsets.right+
")x("+frameInsets.top+
"+"+dimension.height+
"+"+frameInsets.bottom+
")+"+x2+
"+"+y2);
504 frame.setBounds(x2, y2, dimension.width+frameInsets.left+frameInsets.right, dimension.height+frameInsets.top+frameInsets.bottom);
508 if (this.frame !=
null) {
542 frame.createBufferStrategy(2);
545 final Insets insets =
frame.getInsets();
548 debugScreenWrite(
"setResolutionPost: offset="+
offsetX+
"x"+
offsetY+
" insets: top="+insets.top+
", bottom="+insets.bottom+
", left="+insets.left+
", right="+insets.right);
551 frame.requestFocusInWindow();
583 debugScreenWrite(
"updateWindowSize: gui size="+this.windowWidth+
"x"+this.windowHeight);
599 final GraphicsConfiguration graphicsConfiguration =
graphicsDevice.getDefaultConfiguration();
600 final Insets screenInsets = Toolkit.getDefaultToolkit().getScreenInsets(graphicsConfiguration);
601 debugScreenWrite(
"getMaxWindowDimension: screen insets: top="+screenInsets.top+
", bottom="+screenInsets.bottom+
", left="+screenInsets.left+
", right="+screenInsets.right);
603 final int maxWidth =
maximumWindowBounds.width-screenInsets.left-screenInsets.right-frameInsets.left-frameInsets.right;
604 final int maxHeight =
maximumWindowBounds.height-screenInsets.top-screenInsets.bottom-frameInsets.top-frameInsets.bottom;
605 debugScreenWrite(
"getMaxWindowDimension: maximum window dimension: "+maxWidth+
"x"+maxHeight);
606 return new Dimension(maxWidth, maxHeight);
618 assert
frame !=
null;
620 assert
frame !=
null;
622 assert
frame !=
null;
624 assert
frame !=
null;
634 public void redraw(@NotNull
final Graphics g) {
644 for (
int ig = 0; ig < 3; ig++) {
659 g.setColor(Color.BLACK);
660 assert
frame !=
null;
661 final int width =
frame.getWidth();
662 assert
frame !=
null;
663 final int height =
frame.getHeight();
664 g.fillRect(0, 0, width, height);
675 public boolean openDialog(@NotNull
final Gui dialog,
final boolean autoCloseOnDeactivate) {
686 dialog.activateDefaultElement();
687 dialog.setGuiAutoCloseListener(autoCloseOnDeactivate ? () ->
closeDialog(dialog) :
null);
739 return OpenDialogsIterator::new;
779 dialog.setActiveElementActive(
false);
795 dialog.setActiveElementActive(
false);
800 dialog.setGuiAutoCloseListener(
null);
802 dialog.activateDefaultElement();
812 if (this.tooltip !=
null) {
816 if (this.tooltip !=
null) {
837 if (dialog.isHidden(prevRendererGuiState)) {
881 final Point mouse =
frame ==
null ? null :
frame.getMousePosition(
true);
888 if (dialog.isWithinDrawingArea(mouse.x, mouse.y)) {
889 final MouseEvent mouseEvent =
new MouseEvent(
frame, 0, System.currentTimeMillis(), 0, mouse.x, mouse.y, 0,
false);
928 final Point mouse =
frame ==
null ? null :
frame.getMousePosition(
true);
935 assert
frame !=
null;
939 if (dialog.isWithinDrawingArea(mouse.x, mouse.y)) {
940 final MouseEvent mouseEvent =
new MouseEvent(
frame, 0, System.currentTimeMillis(), 0, mouse.x, mouse.y, 0,
false);
947 assert
frame !=
null;
957 assert
frame !=
null;
974 if (dialog.deactivateCommandInput()) {
977 if (dialog.isModal()) {
996 if (buffer !=
null) {
999 if (dialog.isModal()) {
1017 return buffer ==
null ? null : buffer.
getBuffer();
1027 if (metaElementList !=
null) {
1043 if (textArea1 !=
null) {
1051 if (textArea2 !=
null) {
1056 if (dialog.isModal()) {
1088 return it.hasPrevious();
1094 return it.previous();
1098 public void remove() {
1099 throw new UnsupportedOperationException(
"remove() not implemented");
1128 for (Component result = component; result !=
null; result = result.getParent()) {
1132 if (result instanceof
final JViewport viewport) {
1133 final Point position = viewport.getViewPosition();
1134 mouseEvent.translatePoint(-position.x, -position.y);
1149 final MouseEvent ce = e;
1152 final int eX = ce.getX();
1153 final int eY = ce.getY();
1156 elected =
getElementFromPoint(dialog, eX-dialog.getComponent().getX(), eY-dialog.getComponent().getY());
1158 if (elected !=
null) {
1162 if (dialog.isModal()) {
1167 if (elected ==
null) {
1188 return gui.getElementFromPoint(x, y);
1205 }
catch (
final IOException ex) {
1206 System.err.println(
"Cannot write screen debug: "+ex.getMessage());
1208 throw new AssertionError(ex);
1218 private void addToLayeredPane(@NotNull
final Component component,
final int layer,
final int index) {
1269 if (component instanceof
final Container container) {
1270 for (
int i = 0; i < container.getComponentCount(); i++) {
1283 if (component instanceof
final Container container) {
1284 for (
int i = 0; i < container.getComponentCount(); i++) {
1296 if (component instanceof
final GUIMap map) {
1299 if (component instanceof
final GUIFloorList floorList) {
1302 if (component instanceof
final Container container) {
1303 for (
int i = 0; i < container.getComponentCount(); i++) {
1315 if (component instanceof
final GUIMap map) {
1318 if (component instanceof
final GUIFloorList floorList) {
1321 if (component instanceof
final Container container) {
1322 for (
int i = 0; i < container.getComponentCount(); i++) {
1351 width = Math.max(width, map.getPreferredMapWidth());
1352 height = Math.max(height, map.getPreferredMapHeight());
1354 return new Dimension(width, height);
1362 int minNumLookObjects = Integer.MAX_VALUE;
1364 minNumLookObjects = Math.min(minNumLookObjects, floorList.getNumLookObjects());
1366 if (minNumLookObjects < Integer.MAX_VALUE) {
1367 return minNumLookObjects;
1382 if (textArea ==
null) {
1386 if (!textArea.
getName().equals(
"command")) {
1399 final boolean result =
graphicsDevice.isDisplayChangeSupported();
1409 debugScreenWrite(
"setDisplayMode("+displayMode.getWidth()+
"x"+displayMode.getHeight()+
")");
1420 debugScreenWrite(
"getDisplayMode: "+displayMode.getWidth()+
"x"+displayMode.getHeight());
Abstract base class for text input fields.
void raiseDialog(@NotNull final Gui dialog)
Raises an already opened dialog.
void addMouseTrackerRecursively(@NotNull final Component component)
Adds mouseTracker recursively to all children of a Component.
Utility class for Swing related functions.
void setResolutionPre(@NotNull final Window frame)
Tries to switch to the given resolution.
Combines a list of GUIElements to for a gui.
void openDialogInt(@NotNull final Gui dialog)
Opens a dialog.
final Collection< GUIMap > maps
All GUIMap instances that currentGui and openDialogs contain.
void addComponent(@NotNull final Component component)
Adds a Component.
Dimension getMaxWindowDimension(@NotNull final Insets frameInsets)
Returns the maximum dimension of a frame to fit on the screen.
final CrossfireServerConnection crossfireServerConnection
The CrossfireServerConnection to monitor.
void mousePressed(@Nullable final AbstractGUIElement element, @NotNull final MouseEvent e)
Handles a mouse pressed event.
void setPreferredNumLookObjects(int preferredNumLookObjects)
Sets the maximum number of objects in the ground view.
START
The start screen is active.
void endRendering()
Ends rendering and reverts the display settings.
Abstract base class for gui elements implementing text fields.
Buffer getBuffer()
Returns the Buffer instance containing the text messages.
Adds encoding/decoding of crossfire protocol packets to a ServerConnection.
final GraphicsDevice graphicsDevice
The used GraphicsDevice.
void setCurrentGui(@NotNull final Gui gui)
Sets the Gui to display.
final Rectangle maximumWindowBounds
The maximal size of a window.
boolean handleKeyPress(@NotNull final KeyEvent2 e)
Dispatches a key press KeyEvent.
int windowHeight
The height of the client area in pixels.
int offsetY
The y-offset of the visible window.
boolean openDialogsRemove(@NotNull final Gui dialog)
Removes a dialog from openDialogs.
boolean setFullScreenMode(@NotNull final JFrame frame, @Nullable final Resolution resolution)
Tries to switch to the given resolution.
boolean isFullScreen
Records whether full-screen mode is active.
Abstract base class for GUI elements to be shown in Guis.
boolean isDialogOpen(@NotNull final Gui dialog)
Returns whether a given dialog is currently visible.
void setResolutionPost(@NotNull final Window frame, @NotNull final Dimension dimension)
Tries to switch to the given resolution.
AbstractGUIElement findElement(@NotNull final MouseEvent e)
Finds the gui element for a given MouseEvent.
final MouseWheelListener mouseWheelListener
A MouseInputListener that forwards to mouseTracker.
final ListIterator< Gui > it
The backing list iterator; it returns the elements in reversed order.
void setSelectedHostname(@NotNull final String serverName)
Selects a server entry.
void setTooltip(@Nullable final Component tooltip)
Sets the tooltip to use, or.
Iterable< Gui > getOpenDialogs()
Returns all open dialogs in reverse painting order; the first element is the top-most dialog.
void paintActiveComponent(@NotNull final Graphics g)
Marks the active component in a Graphics instance.
static final int DEFAULT_MAP_WIDTH
The default map width to request from the server.
void mouseExited(@NotNull final MouseEvent e)
Handles a mouse exited event.
boolean isDisplayChangeSupported()
Returns the graphicsDevice supports low-level display changes.
void setPreferredMapSize(int preferredMapWidth, int preferredMapHeight)
Sets the preferred map size.
AbstractGUIElement getElementFromPoint(@NotNull final Gui gui, final int eX, final int eY)
Determines the GUIElement for a given coordinate with a given Gui instance.
Represents a pressed or released key.
int getWindowHeight()
Returns the height of the client area.
A gui element implementing the message window.
A list of event listeners.
void redraw(@NotNull final Graphics g)
Paints the view into the given graphics instance.
void removeMouseTracker(@NotNull final Component component)
Removes mouseTracker from a Component.
void setDisplayMode(@NotNull final DisplayMode displayMode)
Sets the display mode of the graphicsDevice.
void addToLayeredPane(@NotNull final Component component, final int layer, final int index)
Adds a component to layeredPane.
void mouseMoved(@Nullable final AbstractGUIElement element, @NotNull final MouseEvent e)
Handles a mouse moved event.
boolean deactivateCommandInput()
Deactivates the command input text field.
An Iterator that returns all open dialogs in painting order.
void setWindowMode(@NotNull final JFrame frame, @Nullable final Resolution resolution, @NotNull final Resolution minResolution, final boolean fixedSize)
Tries to switch to the given resolution.
boolean handleKeyPress(@NotNull final KeyEvent2 e)
Dispatches a key press KeyEvent.
Interface defining an abstract GUI element.
int getWindowWidth()
Returns the width of the client area.
final MouseInputListener mouseInputListener
A MouseInputListener that forwards to mouseTracker.
Component tooltip
The tooltip to use, or.
void mouseClicked(@Nullable final AbstractGUIElement element, @NotNull final MouseEvent e)
Handles a mouse clicked event.
void debugScreenWrite(@NotNull final CharSequence message)
Writes a message to the screen debug.
final MouseTracker mouseTracker
The MouseTracker instance.
Dimension getMapSize()
Returns the map size in squares.
int getNumLookObjects()
Returns the number of ground view objects to request from the server.
BufferStrategy bufferStrategy
The current BufferStrategy.
final ComponentListener componentListener
The ComponentListener attached to frame.
static final DateTimeFormatter FORMATTER
A formatter for timestamps.
void removeMouseTrackerRecursively(@NotNull final Component component)
Removes mouseTracker recursively from all children of a Component.
void setGuiState(@NotNull final RendererGuiState rendererGuiState)
Sets the current gui state.
void openDialogsAdd(@NotNull final Gui dialog)
Adds a dialog to openDialogs.
boolean openDialog(@NotNull final Gui dialog, final boolean autoCloseOnDeactivate)
Opens a dialog.
static Buffer getActiveMessageBuffer(@NotNull final Gui gui)
Returns the active message buffer for a Gui instance.
void updateWindowSize(final int windowWidth, final int windowHeight)
Updates the window size for rendering from the main window size.
Gui currentGui
The currently displayed Gui.
Manages the contents of the contents of a log window.
Renders a Gui instance into a Frame.
void mouseDragged(@Nullable final GUIElement element, @NotNull final MouseEvent e)
Handles a mouse dragged event.
A GUIList instance that displays GUIItemItem instances.
int windowWidth
The width of the client area in pixels.
Information about JXClient's screen/window resolution.
static final int DEFAULT_MAP_HEIGHT
The default map height to request from the server.
void addGuiStateListener(@NotNull final RendererGuiStateListener listener)
Adds a gui state listener to be notified about rendererGuiState changes.
final Container layeredPane
The JLayeredPane added as the top-level component to frame.
final EventListenerList2< RendererGuiStateListener > rendererGuiStateListeners
Listeners to be notified about rendererGuiState changes.
void updateServerSettings()
Updates server based settings to current screen size.
JComponent getComponent()
Returns the JComponent for this instance.
String getName()
Returns the internal name of this gui element.
void mouseWheelMoved(@Nullable final GUIElement element, @NotNull final MouseWheelEvent e)
Handles a mouse wheel event.
JFrame frame
The associated JFrame.
void clearGUI(@NotNull final Gui gui)
Sets a gui to display and clears the display.
void setFullScreenWindow(@Nullable final Window window)
Enter full-screen mode, or return to windowed mode.
final Collection< GUIFloorList > floorLists
The GUIItemList instances that currentGui and openDialogs contain and that display floor items.
final Writer debugScreen
The Writer to write screen debug to or.
void removeComponent(@NotNull final Component component)
Removes a Component.
boolean closeDialog(@NotNull final Gui dialog)
Closes a dialog.
DisplayMode getDisplayMode()
Returns the current display mode of the graphicsDevice.
GUIText activateCommandInput()
Activates the command input text field.
static AbstractGUIElement findElement(@NotNull final Component component, @NotNull final MouseEvent mouseEvent)
Finds the gui element a given Component is part of.
public< T extends GUIElement > T getFirstElement(@NotNull final Class< T > class_)
Returns the first gui element of this gui belonging to the given class.
JXCWindowRenderer(@NotNull final MouseTracker mouseTracker, @NotNull final CrossfireServerConnection crossfireServerConnection, @Nullable final Writer debugScreen)
Creates a new instance.
RendererGuiState getGuiState()
Returns the current gui state.
Buffer getActiveMessageBuffer()
Returns the active message buffer.
void removeFromLayeredPane(@NotNull final Component component)
Removes a component from layeredPane.
boolean deactivateCommandInput()
Deactivates the command text input field of this dialog.
Point getCenterPoint()
Returns the Point where windows should be centered.
void mouseEntered(@Nullable final AbstractGUIElement element, @NotNull final MouseEvent e)
Handles a mouse entered event.
boolean isFullScreenSupported()
Returns whether the graphicsDevice supports full-screen exclusive mode.
int offsetX
The x-offset of the visible window.
final List< Gui > openDialogs
Currently opened dialogs.
RendererGuiState rendererGuiState
The current gui state.
void redrawBlack(@NotNull final Graphics g)
Repaints all to black.
final GraphicsEnvironment graphicsEnvironment
The used GraphicsEnvironment.
void setActive(final boolean active)
Sets the active state of a GUI element.
void addMouseTracker(@NotNull final Component component)
Adds mouseTracker to a Component.
static void invokeAndWait(@NotNull final Runnable runnable)
Calls SwingUtilities#invokeAndWait(Runnable) if not on the EDT or calls the Runnable directly if on t...
void mouseReleased(@Nullable final AbstractGUIElement element, @NotNull final MouseEvent e)
Handles a mouse released event.
boolean toggleDialog(@NotNull final Gui dialog)
Toggles a dialog: if the dialog is not shown, show it; else hide it.
Interface for listeners interested in gui state changes.
A GUIItemList for floor views.
static final int DEFAULT_NUM_LOOK_OBJECTS
The default number of ground view objects.
boolean wasDisplayed
Records whether the frame has been displayed before.
final DisplayMode defaultDisplayMode
The default screen mode that was active when the client did start.
All gui states of JXCWindowRenderer.
Tracks mouse actions and delivers mouse events to affected GUIElement.
static GUIText activateCommandInput(@NotNull final Gui gui)
Returns the first command text field of a gui and make it active.