Updated colors and design
This commit is contained in:
2
pom.xml
2
pom.xml
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
<groupId>org.openautonomousconnection</groupId>
|
<groupId>org.openautonomousconnection</groupId>
|
||||||
<artifactId>OACSwing</artifactId>
|
<artifactId>OACSwing</artifactId>
|
||||||
<version>1.0.0-BETA.1.0</version>
|
<version>1.0.0-BETA.1.1</version>
|
||||||
<organization>
|
<organization>
|
||||||
<name>Open Autonomous Connection</name>
|
<name>Open Autonomous Connection</name>
|
||||||
<url>https://open-autonomous-connection.org/</url>
|
<url>https://open-autonomous-connection.org/</url>
|
||||||
|
|||||||
@@ -81,6 +81,7 @@ public class OACButton extends JButton implements OACPressable {
|
|||||||
setContentAreaFilled(false);
|
setContentAreaFilled(false);
|
||||||
setOpaque(false);
|
setOpaque(false);
|
||||||
setFocusPainted(false);
|
setFocusPainted(false);
|
||||||
|
setBorderPainted(false);
|
||||||
|
|
||||||
if (!isEnabled() && getDisabledColor() != null) {
|
if (!isEnabled() && getDisabledColor() != null) {
|
||||||
super.setBackground(getDisabledColor());
|
super.setBackground(getDisabledColor());
|
||||||
@@ -182,4 +183,4 @@ public class OACButton extends JButton implements OACPressable {
|
|||||||
g2.dispose();
|
g2.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ package org.openautonomousconnection.oacswing.component;
|
|||||||
import org.openautonomousconnection.oacswing.component.design.DesignManager;
|
import org.openautonomousconnection.oacswing.component.design.DesignManager;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
|
import javax.swing.border.EmptyBorder;
|
||||||
|
import javax.swing.border.LineBorder;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.awt.event.ComponentAdapter;
|
import java.awt.event.ComponentAdapter;
|
||||||
import java.awt.event.ComponentEvent;
|
import java.awt.event.ComponentEvent;
|
||||||
@@ -64,6 +66,7 @@ public class OACFrame extends JFrame {
|
|||||||
setBackground(new Color(0, 0, 0, 1));
|
setBackground(new Color(0, 0, 0, 1));
|
||||||
|
|
||||||
roundedRoot.setLayout(new BorderLayout());
|
roundedRoot.setLayout(new BorderLayout());
|
||||||
|
roundedRoot.setBorder(new EmptyBorder(TITLE_BAR_HEIGHT, 0, 0, 0));
|
||||||
setContentPane(roundedRoot);
|
setContentPane(roundedRoot);
|
||||||
|
|
||||||
titleBar = new OACTitleBar(this);
|
titleBar = new OACTitleBar(this);
|
||||||
@@ -79,16 +82,20 @@ public class OACFrame extends JFrame {
|
|||||||
@Override
|
@Override
|
||||||
public void componentResized(ComponentEvent e) {
|
public void componentResized(ComponentEvent e) {
|
||||||
titleRoot.setBounds(0, 0, getWidth(), TITLE_BAR_HEIGHT);
|
titleRoot.setBounds(0, 0, getWidth(), TITLE_BAR_HEIGHT);
|
||||||
|
updateWindowChrome();
|
||||||
roundedRoot.repaint();
|
roundedRoot.repaint();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void componentShown(ComponentEvent e) {
|
public void componentShown(ComponentEvent e) {
|
||||||
titleRoot.setBounds(0, 0, getWidth(), TITLE_BAR_HEIGHT);
|
titleRoot.setBounds(0, 0, getWidth(), TITLE_BAR_HEIGHT);
|
||||||
|
updateWindowChrome();
|
||||||
roundedRoot.repaint();
|
roundedRoot.repaint();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
addWindowStateListener(e -> updateWindowChrome());
|
||||||
|
|
||||||
setSize(900, 600);
|
setSize(900, 600);
|
||||||
|
|
||||||
SwingUtilities.invokeLater(() -> {
|
SwingUtilities.invokeLater(() -> {
|
||||||
@@ -99,6 +106,7 @@ public class OACFrame extends JFrame {
|
|||||||
installResizeHandling();
|
installResizeHandling();
|
||||||
|
|
||||||
DesignManager.apply(this);
|
DesignManager.apply(this);
|
||||||
|
updateWindowChrome();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -142,18 +150,29 @@ public class OACFrame extends JFrame {
|
|||||||
MouseAdapter adapter = new MouseAdapter() {
|
MouseAdapter adapter = new MouseAdapter() {
|
||||||
@Override
|
@Override
|
||||||
public void mouseMoved(MouseEvent e) {
|
public void mouseMoved(MouseEvent e) {
|
||||||
|
if (isInFullscreenState()) {
|
||||||
|
resizeCursor = Cursor.DEFAULT_CURSOR;
|
||||||
|
setCursor(Cursor.getDefaultCursor());
|
||||||
|
return;
|
||||||
|
}
|
||||||
resizeCursor = getResizeCursor(e);
|
resizeCursor = getResizeCursor(e);
|
||||||
setCursor(Cursor.getPredefinedCursor(resizeCursor));
|
setCursor(Cursor.getPredefinedCursor(resizeCursor));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void mousePressed(MouseEvent e) {
|
public void mousePressed(MouseEvent e) {
|
||||||
|
if (isInFullscreenState()) {
|
||||||
|
dragStart = null;
|
||||||
|
startBounds = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
dragStart = e.getLocationOnScreen();
|
dragStart = e.getLocationOnScreen();
|
||||||
startBounds = getBounds();
|
startBounds = getBounds();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void mouseDragged(MouseEvent e) {
|
public void mouseDragged(MouseEvent e) {
|
||||||
|
if (isInFullscreenState()) return;
|
||||||
if (resizeCursor == Cursor.DEFAULT_CURSOR) return;
|
if (resizeCursor == Cursor.DEFAULT_CURSOR) return;
|
||||||
|
|
||||||
Point dragNow = e.getLocationOnScreen();
|
Point dragNow = e.getLocationOnScreen();
|
||||||
@@ -207,6 +226,10 @@ public class OACFrame extends JFrame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private int getResizeCursor(MouseEvent e) {
|
private int getResizeCursor(MouseEvent e) {
|
||||||
|
if (isInFullscreenState()) {
|
||||||
|
return Cursor.DEFAULT_CURSOR;
|
||||||
|
}
|
||||||
|
|
||||||
int x = e.getX();
|
int x = e.getX();
|
||||||
int y = e.getY();
|
int y = e.getY();
|
||||||
int w = e.getComponent().getWidth();
|
int w = e.getComponent().getWidth();
|
||||||
@@ -229,13 +252,29 @@ public class OACFrame extends JFrame {
|
|||||||
return Cursor.DEFAULT_CURSOR;
|
return Cursor.DEFAULT_CURSOR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isInFullscreenState() {
|
||||||
|
return (getExtendedState() & Frame.MAXIMIZED_BOTH) == Frame.MAXIMIZED_BOTH;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Root panel that paints a near-transparent full-window layer (alpha=1)
|
* Root panel that paints a near-transparent full-window layer (alpha=1)
|
||||||
* to prevent click-through, then paints the rounded background and clips children.
|
* to prevent click-through, then paints the rounded background and clips children.
|
||||||
*/
|
*/
|
||||||
|
private void updateWindowChrome() {
|
||||||
|
boolean fullscreen = isInFullscreenState();
|
||||||
|
roundedRoot.setArc(fullscreen ? 0 : CORNER_ARC);
|
||||||
|
if (fullscreen) {
|
||||||
|
getRootPane().setBorder(new LineBorder(DesignManager.resolveBorderColor(Color.GRAY), 1));
|
||||||
|
setCursor(Cursor.getDefaultCursor());
|
||||||
|
} else {
|
||||||
|
getRootPane().setBorder(new EmptyBorder(0, 0, 0, 0));
|
||||||
|
}
|
||||||
|
repaint();
|
||||||
|
}
|
||||||
|
|
||||||
private static final class RoundedRootPanel extends OACPanel {
|
private static final class RoundedRootPanel extends OACPanel {
|
||||||
|
|
||||||
private final int arc;
|
private int arc;
|
||||||
|
|
||||||
private RoundedRootPanel(int arc) {
|
private RoundedRootPanel(int arc) {
|
||||||
super(new BorderLayout());
|
super(new BorderLayout());
|
||||||
@@ -243,6 +282,10 @@ public class OACFrame extends JFrame {
|
|||||||
setOpaque(false);
|
setOpaque(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setArc(int arc) {
|
||||||
|
this.arc = Math.max(0, arc);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void paintComponent(Graphics g) {
|
protected void paintComponent(Graphics g) {
|
||||||
Graphics2D g2 = (Graphics2D) g.create();
|
Graphics2D g2 = (Graphics2D) g.create();
|
||||||
@@ -292,4 +335,4 @@ public class OACFrame extends JFrame {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,9 +5,14 @@
|
|||||||
package org.openautonomousconnection.oacswing.component;
|
package org.openautonomousconnection.oacswing.component;
|
||||||
|
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
|
import org.openautonomousconnection.oacswing.component.design.DesignManager;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
|
import javax.swing.border.EmptyBorder;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
|
import java.awt.event.WindowAdapter;
|
||||||
|
import java.awt.event.WindowEvent;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
public class OACOptionPane extends JOptionPane implements OACComponent {
|
public class OACOptionPane extends JOptionPane implements OACComponent {
|
||||||
public OACOptionPane() {
|
public OACOptionPane() {
|
||||||
@@ -38,6 +43,140 @@ public class OACOptionPane extends JOptionPane implements OACComponent {
|
|||||||
super(message, messageType, optionType, icon, options, initialValue);
|
super(message, messageType, optionType, icon, options, initialValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init() {
|
||||||
|
setOpaque(true);
|
||||||
|
setBackground(DesignManager.resolveBackground(OACOptionPane.class, getBackground()));
|
||||||
|
setForeground(DesignManager.resolveForeground(OACOptionPane.class, getForeground()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int showOptionDialog(Component parentComponent,
|
||||||
|
Object message,
|
||||||
|
String title,
|
||||||
|
int optionType,
|
||||||
|
int messageType,
|
||||||
|
Icon icon,
|
||||||
|
Object[] options,
|
||||||
|
Object initialValue) throws HeadlessException {
|
||||||
|
AtomicInteger result = new AtomicInteger(CLOSED_OPTION);
|
||||||
|
OACDialog dialog = new OACDialog(JOptionPane.getFrameForComponent(parentComponent), title, true);
|
||||||
|
dialog.setUndecorated(true);
|
||||||
|
dialog.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
|
||||||
|
dialog.setContentPane(buildDialogContent(title, message, icon, optionType, options, result, dialog));
|
||||||
|
dialog.setResizable(false);
|
||||||
|
dialog.addWindowListener(new WindowAdapter() {
|
||||||
|
@Override
|
||||||
|
public void windowClosing(WindowEvent e) {
|
||||||
|
result.set(CLOSED_OPTION);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
dialog.pack();
|
||||||
|
dialog.setMinimumSize(new Dimension(420, dialog.getHeight()));
|
||||||
|
dialog.setLocationRelativeTo(parentComponent);
|
||||||
|
dialog.setVisible(true);
|
||||||
|
dialog.dispose();
|
||||||
|
return result.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Container buildDialogContent(String title,
|
||||||
|
Object message,
|
||||||
|
Icon icon,
|
||||||
|
int optionType,
|
||||||
|
Object[] options,
|
||||||
|
AtomicInteger result,
|
||||||
|
OACDialog dialog) {
|
||||||
|
OACPanel root = new OACPanel(new BorderLayout());
|
||||||
|
Color background = DesignManager.resolveBackground(OACOptionPane.class, root.getBackground());
|
||||||
|
Color headerBackground = DesignManager.resolveBackground(OACTitleBar.class, background.darker());
|
||||||
|
Color foreground = DesignManager.resolveForeground(OACOptionPane.class, Color.LIGHT_GRAY);
|
||||||
|
Color borderColor = DesignManager.resolveBorderColor(foreground.darker());
|
||||||
|
|
||||||
|
root.setBackground(background);
|
||||||
|
root.setBorder(BorderFactory.createLineBorder(borderColor, 1));
|
||||||
|
|
||||||
|
OACPanel header = new OACPanel(new BorderLayout());
|
||||||
|
header.setBorder(new EmptyBorder(10, 12, 10, 12));
|
||||||
|
header.setBackground(headerBackground);
|
||||||
|
JSeparator separator = new JSeparator(SwingConstants.HORIZONTAL);
|
||||||
|
separator.setForeground(borderColor);
|
||||||
|
separator.setBackground(borderColor);
|
||||||
|
header.add(separator, BorderLayout.SOUTH);
|
||||||
|
|
||||||
|
OACLabel titleLabel = new OACLabel(title == null ? "" : title);
|
||||||
|
titleLabel.setForeground(foreground);
|
||||||
|
header.add(titleLabel, BorderLayout.WEST);
|
||||||
|
|
||||||
|
OACPanel center = new OACPanel(new BorderLayout(10, 0));
|
||||||
|
center.setBackground(background);
|
||||||
|
center.setBorder(new EmptyBorder(14, 12, 12, 12));
|
||||||
|
|
||||||
|
if (icon != null) {
|
||||||
|
OACLabel iconLabel = new OACLabel(icon);
|
||||||
|
iconLabel.setForeground(foreground);
|
||||||
|
center.add(iconLabel, BorderLayout.WEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
JTextArea messageArea = new JTextArea(String.valueOf(message));
|
||||||
|
messageArea.setEditable(false);
|
||||||
|
messageArea.setLineWrap(true);
|
||||||
|
messageArea.setWrapStyleWord(true);
|
||||||
|
messageArea.setOpaque(false);
|
||||||
|
messageArea.setForeground(foreground);
|
||||||
|
messageArea.setBorder(null);
|
||||||
|
center.add(messageArea, BorderLayout.CENTER);
|
||||||
|
|
||||||
|
OACPanel buttons = new OACPanel(new FlowLayout(FlowLayout.RIGHT, 8, 8));
|
||||||
|
buttons.setBackground(background);
|
||||||
|
|
||||||
|
Object[] displayOptions = resolveOptions(optionType, options);
|
||||||
|
for (int i = 0; i < displayOptions.length; i++) {
|
||||||
|
final int index = i;
|
||||||
|
OACButton button = new OACButton(String.valueOf(displayOptions[i]));
|
||||||
|
button.initDesign();
|
||||||
|
button.setBackground(DesignManager.resolveBackground(OACButton.class, button.getBackground()));
|
||||||
|
button.setForeground(DesignManager.resolveForeground(OACButton.class, button.getForeground()));
|
||||||
|
button.setHoveredColor(DesignManager.resolveHovered(OACButton.class, button.getBackground().brighter()));
|
||||||
|
button.setPressedColor(DesignManager.resolvePressed(OACButton.class, button.getBackground().darker()));
|
||||||
|
button.setBorder(BorderFactory.createLineBorder(borderColor, 1, true));
|
||||||
|
button.setPreferredSize(new Dimension(100, 32));
|
||||||
|
button.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
|
||||||
|
button.addActionListener(e -> {
|
||||||
|
result.set(mapResult(optionType, options, index));
|
||||||
|
dialog.dispose();
|
||||||
|
});
|
||||||
|
buttons.add(button);
|
||||||
|
}
|
||||||
|
|
||||||
|
root.add(header, BorderLayout.NORTH);
|
||||||
|
root.add(center, BorderLayout.CENTER);
|
||||||
|
root.add(buttons, BorderLayout.SOUTH);
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Object[] resolveOptions(int optionType, Object[] options) {
|
||||||
|
if (options != null && options.length > 0) {
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
return switch (optionType) {
|
||||||
|
case YES_NO_OPTION -> new Object[]{"Yes", "No"};
|
||||||
|
case YES_NO_CANCEL_OPTION -> new Object[]{"Yes", "No", "Cancel"};
|
||||||
|
case OK_CANCEL_OPTION -> new Object[]{"OK", "Cancel"};
|
||||||
|
default -> new Object[]{"OK"};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int mapResult(int optionType, Object[] providedOptions, int clickedIndex) {
|
||||||
|
if (providedOptions != null && providedOptions.length > 0) {
|
||||||
|
return clickedIndex;
|
||||||
|
}
|
||||||
|
return switch (optionType) {
|
||||||
|
case YES_NO_OPTION -> clickedIndex == 0 ? YES_OPTION : NO_OPTION;
|
||||||
|
case YES_NO_CANCEL_OPTION -> clickedIndex == 0 ? YES_OPTION : (clickedIndex == 1 ? NO_OPTION : CANCEL_OPTION);
|
||||||
|
case OK_CANCEL_OPTION -> clickedIndex == 0 ? OK_OPTION : CANCEL_OPTION;
|
||||||
|
default -> OK_OPTION;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Component add(Component comp) {
|
public Component add(Component comp) {
|
||||||
this.initOther(comp);
|
this.initOther(comp);
|
||||||
|
|||||||
@@ -5,8 +5,10 @@
|
|||||||
package org.openautonomousconnection.oacswing.component;
|
package org.openautonomousconnection.oacswing.component;
|
||||||
|
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
|
import org.openautonomousconnection.oacswing.component.design.DesignManager;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
|
import javax.swing.border.EmptyBorder;
|
||||||
import javax.swing.text.Document;
|
import javax.swing.text.Document;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
|
|
||||||
@@ -31,6 +33,39 @@ public class OACPasswordField extends JPasswordField implements OACComponent {
|
|||||||
super(doc, txt, columns);
|
super(doc, txt, columns);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init() {
|
||||||
|
setOpaque(true);
|
||||||
|
applyInputBorder();
|
||||||
|
setCaretColor(getForeground());
|
||||||
|
setSelectionColor(getForeground().darker());
|
||||||
|
setSelectedTextColor(getBackground().brighter());
|
||||||
|
setPreferredSize(new Dimension(Math.max(160, getPreferredSize().width), 34));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateUI() {
|
||||||
|
super.updateUI();
|
||||||
|
applyInputBorder();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void applyInputBorder() {
|
||||||
|
setBorder(new EmptyBorder(6, 10, 6, 10));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void paintBorder(Graphics g) {
|
||||||
|
Graphics2D g2 = (Graphics2D) g.create();
|
||||||
|
try {
|
||||||
|
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||||
|
g2.setColor(DesignManager.resolveBorderColor(getForeground()));
|
||||||
|
g2.setStroke(new BasicStroke(2f));
|
||||||
|
g2.drawRoundRect(1, 1, getWidth() - 3, getHeight() - 3, 10, 10);
|
||||||
|
} finally {
|
||||||
|
g2.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Component add(Component comp) {
|
public Component add(Component comp) {
|
||||||
this.initOther(comp);
|
this.initOther(comp);
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
package org.openautonomousconnection.oacswing.component;
|
package org.openautonomousconnection.oacswing.component;
|
||||||
|
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
|
import org.openautonomousconnection.oacswing.component.design.DesignManager;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import javax.swing.text.Document;
|
import javax.swing.text.Document;
|
||||||
@@ -35,6 +36,16 @@ public class OACTextArea extends JTextArea implements OACComponent {
|
|||||||
super(doc, text, rows, columns);
|
super(doc, text, rows, columns);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init() {
|
||||||
|
setOpaque(true);
|
||||||
|
setMargin(new Insets(6, 10, 6, 10));
|
||||||
|
setBorder(DesignManager.createTextComponentBorder());
|
||||||
|
setCaretColor(getForeground());
|
||||||
|
setSelectionColor(getForeground().darker());
|
||||||
|
setSelectedTextColor(getBackground().brighter());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Component add(Component comp) {
|
public Component add(Component comp) {
|
||||||
this.initOther(comp);
|
this.initOther(comp);
|
||||||
|
|||||||
@@ -4,7 +4,12 @@
|
|||||||
|
|
||||||
package org.openautonomousconnection.oacswing.component;
|
package org.openautonomousconnection.oacswing.component;
|
||||||
|
|
||||||
|
import org.openautonomousconnection.oacswing.border.RoundedBorder;
|
||||||
|
import org.openautonomousconnection.oacswing.component.design.DesignManager;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
|
import javax.swing.border.CompoundBorder;
|
||||||
|
import javax.swing.border.EmptyBorder;
|
||||||
import javax.swing.text.Document;
|
import javax.swing.text.Document;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
|
|
||||||
@@ -29,6 +34,29 @@ public class OACTextField extends JTextField implements OACComponent {
|
|||||||
super(doc, text, columns);
|
super(doc, text, columns);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init() {
|
||||||
|
setOpaque(true);
|
||||||
|
applyInputBorder();
|
||||||
|
setCaretColor(getForeground());
|
||||||
|
setSelectionColor(getForeground().darker());
|
||||||
|
setSelectedTextColor(getBackground().brighter());
|
||||||
|
setPreferredSize(new Dimension(Math.max(160, getPreferredSize().width), 34));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateUI() {
|
||||||
|
super.updateUI();
|
||||||
|
applyInputBorder();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void applyInputBorder() {
|
||||||
|
setBorder(new CompoundBorder(
|
||||||
|
new RoundedBorder(DesignManager.resolveBorderColor(getForeground()), 10, 2),
|
||||||
|
new EmptyBorder(6, 10, 6, 10)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Component add(Component comp) {
|
public Component add(Component comp) {
|
||||||
this.initOther(comp);
|
this.initOther(comp);
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
package org.openautonomousconnection.oacswing.component;
|
package org.openautonomousconnection.oacswing.component;
|
||||||
|
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
|
import org.openautonomousconnection.oacswing.component.design.DesignManager;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import javax.swing.text.StyledDocument;
|
import javax.swing.text.StyledDocument;
|
||||||
@@ -18,6 +19,16 @@ public class OACTextPane extends JTextPane implements OACComponent {
|
|||||||
super(doc);
|
super(doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init() {
|
||||||
|
setOpaque(true);
|
||||||
|
setMargin(new Insets(6, 10, 6, 10));
|
||||||
|
setBorder(DesignManager.createTextComponentBorder());
|
||||||
|
setCaretColor(getForeground());
|
||||||
|
setSelectionColor(getForeground().darker());
|
||||||
|
setSelectedTextColor(getBackground().brighter());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Component add(Component comp) {
|
public Component add(Component comp) {
|
||||||
this.initOther(comp);
|
this.initOther(comp);
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ package org.openautonomousconnection.oacswing.component;
|
|||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
import org.openautonomousconnection.oacswing.component.design.DesignManager;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import javax.swing.border.EmptyBorder;
|
import javax.swing.border.EmptyBorder;
|
||||||
@@ -39,6 +40,9 @@ public class OACTitleBar extends OACPanel {
|
|||||||
super(new BorderLayout());
|
super(new BorderLayout());
|
||||||
this.frame = frame;
|
this.frame = frame;
|
||||||
|
|
||||||
|
setOpaque(true);
|
||||||
|
setBackground(DesignManager.resolveBackground(OACTitleBar.class, getBackground()));
|
||||||
|
setForeground(DesignManager.resolveForeground(OACTitleBar.class, getForeground()));
|
||||||
setPreferredSize(new Dimension(1, HEIGHT));
|
setPreferredSize(new Dimension(1, HEIGHT));
|
||||||
setBorder(new EmptyBorder(6, 10, 6, 10));
|
setBorder(new EmptyBorder(6, 10, 6, 10));
|
||||||
|
|
||||||
@@ -170,4 +174,4 @@ public class OACTitleBar extends OACPanel {
|
|||||||
|
|
||||||
frame.dispatchEvent(new ComponentEvent(this, ComponentEvent.COMPONENT_RESIZED));
|
frame.dispatchEvent(new ComponentEvent(this, ComponentEvent.COMPONENT_RESIZED));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,11 +10,23 @@ import org.openautonomousconnection.oacswing.border.RoundedBorder;
|
|||||||
import org.openautonomousconnection.oacswing.component.*;
|
import org.openautonomousconnection.oacswing.component.*;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
|
import javax.swing.border.Border;
|
||||||
|
import javax.swing.border.CompoundBorder;
|
||||||
|
import javax.swing.border.EmptyBorder;
|
||||||
|
import javax.swing.border.LineBorder;
|
||||||
|
import javax.swing.text.JTextComponent;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.event.ContainerAdapter;
|
||||||
|
import java.awt.event.ContainerEvent;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
public class DesignManager {
|
public class DesignManager {
|
||||||
|
private static final String OAC_INIT_PROPERTY = "oac.design.initialized";
|
||||||
|
private static final String OAC_LISTENER_PROPERTY = "oac.design.listener";
|
||||||
|
private static final Border INVISIBLE_BORDER = new EmptyBorder(0, 0, 0, 0);
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
private static Design globalDesign;
|
private static Design globalDesign;
|
||||||
@@ -27,13 +39,13 @@ public class DesignManager {
|
|||||||
OACColor.DARK_INPUT_BUTTON_HOVER,
|
OACColor.DARK_INPUT_BUTTON_HOVER,
|
||||||
OACColor.DARK_INPUT_BUTTON_HOVER,
|
OACColor.DARK_INPUT_BUTTON_HOVER,
|
||||||
OACColor.DARK_INACTIVE_BUTTON,
|
OACColor.DARK_INACTIVE_BUTTON,
|
||||||
true
|
false
|
||||||
));
|
));
|
||||||
|
|
||||||
Design.DARK.getElements().put(OACCheckBox.class, new DesignFlags(OACColor.DARK_INPUT_FIELD));
|
Design.DARK.getElements().put(OACCheckBox.class, new DesignFlags(OACColor.DARK_INPUT_FIELD));
|
||||||
Design.DARK.getElements().put(OACCheckBoxMenuItem.class, new DesignFlags(OACColor.DARK_ITEM));
|
Design.DARK.getElements().put(OACCheckBoxMenuItem.class, new DesignFlags(OACColor.DARK_ITEM));
|
||||||
Design.DARK.getElements().put(OACTextField.class, new DesignFlags(OACColor.DARK_ITEM, OACColor.DARK_TEXT));
|
Design.DARK.getElements().put(OACTextField.class, new DesignFlags(OACColor.DARK_INPUT_FIELD, OACColor.DARK_TEXT));
|
||||||
Design.DARK.getElements().put(OACTextArea.class, new DesignFlags(OACColor.DARK_ITEM, OACColor.DARK_TEXT));
|
Design.DARK.getElements().put(OACTextArea.class, new DesignFlags(OACColor.DARK_INPUT_FIELD, OACColor.DARK_TEXT));
|
||||||
Design.DARK.getElements().put(OACColorChooser.class, new DesignFlags(OACColor.DARK_SECTION));
|
Design.DARK.getElements().put(OACColorChooser.class, new DesignFlags(OACColor.DARK_SECTION));
|
||||||
Design.DARK.getElements().put(OACComboBox.class, new DesignFlags(OACColor.DARK_INPUT_FIELD));
|
Design.DARK.getElements().put(OACComboBox.class, new DesignFlags(OACColor.DARK_INPUT_FIELD));
|
||||||
Design.DARK.getElements().put(OACFrame.class, new DesignFlags(OACColor.DARK_BACKGROUND));
|
Design.DARK.getElements().put(OACFrame.class, new DesignFlags(OACColor.DARK_BACKGROUND));
|
||||||
@@ -44,14 +56,16 @@ public class DesignManager {
|
|||||||
Design.DARK.getElements().put(OACMenuBar.class, new DesignFlags(OACColor.DARK_SECTION));
|
Design.DARK.getElements().put(OACMenuBar.class, new DesignFlags(OACColor.DARK_SECTION));
|
||||||
Design.DARK.getElements().put(OACMenuItem.class, new DesignFlags(OACColor.DARK_ITEM));
|
Design.DARK.getElements().put(OACMenuItem.class, new DesignFlags(OACColor.DARK_ITEM));
|
||||||
Design.DARK.getElements().put(OACOptionPane.class, new DesignFlags(OACColor.DARK_BACKGROUND));
|
Design.DARK.getElements().put(OACOptionPane.class, new DesignFlags(OACColor.DARK_BACKGROUND));
|
||||||
Design.DARK.getElements().put(OACPanel.class, new DesignFlags(OACColor.DARK_BACKGROUND, true));
|
Design.DARK.getElements().put(OACPanel.class, new DesignFlags(OACColor.DARK_BACKGROUND, false));
|
||||||
Design.DARK.getElements().put(OACPasswordField.class, new DesignFlags(OACColor.DARK_INPUT_FIELD));
|
Design.DARK.getElements().put(OACPasswordField.class, new DesignFlags(OACColor.DARK_INPUT_FIELD, OACColor.DARK_TEXT));
|
||||||
Design.DARK.getElements().put(OACPopupMenu.class, new DesignFlags(OACColor.DARK_BACKGROUND));
|
Design.DARK.getElements().put(OACPopupMenu.class, new DesignFlags(OACColor.DARK_BACKGROUND));
|
||||||
Design.DARK.getElements().put(OACProgressBar.class, new DesignFlags(OACColor.DARK_ITEM));
|
Design.DARK.getElements().put(OACProgressBar.class, new DesignFlags(OACColor.DARK_ITEM));
|
||||||
Design.DARK.getElements().put(OACRadioButton.class, new DesignFlags(OACColor.DARK_BUTTON));
|
Design.DARK.getElements().put(OACRadioButton.class, new DesignFlags(OACColor.DARK_BUTTON));
|
||||||
Design.DARK.getElements().put(OACTitleBar.class, new DesignFlags(OACColor.DARK_SECTION));
|
Design.DARK.getElements().put(OACDialog.class, new DesignFlags(OACColor.DARK_BACKGROUND));
|
||||||
|
Design.DARK.getElements().put(OACTitleBar.class, new DesignFlags(OACColor.DARK_HEADER));
|
||||||
|
|
||||||
Design.DARK.border =new RoundedBorder(OACColor.DARK_BORDERS.getColor(), 18, 1);
|
Design.DARK.border = new RoundedBorder(OACColor.DARK_BORDERS.getColor(), 18, 1);
|
||||||
|
globalDesign = Design.DARK;
|
||||||
|
|
||||||
DesignManager.getInstance().registerDesign(Design.DARK);
|
DesignManager.getInstance().registerDesign(Design.DARK);
|
||||||
}
|
}
|
||||||
@@ -73,7 +87,7 @@ public class DesignManager {
|
|||||||
if (globalDesign == null)
|
if (globalDesign == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
DesignFlags designFlags = globalDesign.getElements().get(component.getClass());
|
DesignFlags designFlags = resolveFlags(component.getClass());
|
||||||
|
|
||||||
if (designFlags == null)
|
if (designFlags == null)
|
||||||
return;
|
return;
|
||||||
@@ -96,22 +110,101 @@ public class DesignManager {
|
|||||||
if (disabled != null) pressable.setDisabledColor(disabled.getColor());
|
if (disabled != null) pressable.setDisabledColor(disabled.getColor());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (component instanceof JComponent jComponent) {
|
if (component instanceof Component awtComponent) {
|
||||||
jComponent.setBackground(backgroundColour.getColor());
|
awtComponent.setBackground(backgroundColour.getColor());
|
||||||
|
|
||||||
if (foregroundColour != null) {
|
if (foregroundColour != null) {
|
||||||
jComponent.setForeground(foregroundColour.getColor());
|
awtComponent.setForeground(foregroundColour.getColor());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (component instanceof JComponent jComponent) {
|
||||||
if (hasBorder) {
|
if (hasBorder) {
|
||||||
jComponent.setBorder(globalDesign.getBorder());
|
jComponent.setBorder(globalDesign.getBorder());
|
||||||
jComponent.setOpaque(false);
|
jComponent.setOpaque(false);
|
||||||
|
} else if (!(jComponent instanceof OACTitleBar) && !(jComponent instanceof JTextComponent)) {
|
||||||
|
Border currentBorder = jComponent.getBorder();
|
||||||
|
if (currentBorder == null || hasZeroInsets(currentBorder, jComponent)) {
|
||||||
|
jComponent.setBorder(INVISIBLE_BORDER);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (jComponent instanceof JTextComponent textComponent) {
|
||||||
|
textComponent.setOpaque(true);
|
||||||
|
textComponent.setBorder(createTextComponentBorder());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Boolean.TRUE.equals(jComponent.getClientProperty(OAC_INIT_PROPERTY))) {
|
||||||
|
component.init();
|
||||||
|
jComponent.putClientProperty(OAC_INIT_PROPERTY, Boolean.TRUE);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
component.init();
|
component.init();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean hasZeroInsets(Border border, JComponent component) {
|
||||||
|
Insets insets = border.getBorderInsets(component);
|
||||||
|
return insets.top == 0 && insets.left == 0 && insets.bottom == 0 && insets.right == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DesignFlags getFlagsFor(Class<?> type) {
|
||||||
|
if (globalDesign == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return resolveFlags(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Color resolveBackground(Class<?> type, Color fallback) {
|
||||||
|
DesignFlags flags = getFlagsFor(type);
|
||||||
|
if (flags != null && flags.background() != null) {
|
||||||
|
return flags.background().getColor();
|
||||||
|
}
|
||||||
|
return fallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Color resolveForeground(Class<?> type, Color fallback) {
|
||||||
|
DesignFlags flags = getFlagsFor(type);
|
||||||
|
if (flags != null && flags.foreground() != null) {
|
||||||
|
return flags.foreground().getColor();
|
||||||
|
}
|
||||||
|
if (globalDesign != null && globalDesign.getForegroundColour() != null) {
|
||||||
|
return globalDesign.getForegroundColour().getColor();
|
||||||
|
}
|
||||||
|
return fallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Color resolveHovered(Class<?> type, Color fallback) {
|
||||||
|
DesignFlags flags = getFlagsFor(type);
|
||||||
|
if (flags != null && flags.hovered() != null) {
|
||||||
|
return flags.hovered().getColor();
|
||||||
|
}
|
||||||
|
return fallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Color resolvePressed(Class<?> type, Color fallback) {
|
||||||
|
DesignFlags flags = getFlagsFor(type);
|
||||||
|
if (flags != null && flags.pressed() != null) {
|
||||||
|
return flags.pressed().getColor();
|
||||||
|
}
|
||||||
|
return fallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Border createTextComponentBorder() {
|
||||||
|
Color borderColor = resolveBorderColor(new Color(120, 120, 120));
|
||||||
|
return new CompoundBorder(
|
||||||
|
new LineBorder(borderColor, 2, true),
|
||||||
|
new EmptyBorder(4, 8, 4, 8)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Color resolveBorderColor(Color fallback) {
|
||||||
|
if (globalDesign != null && globalDesign.getBorder() instanceof RoundedBorder roundedBorder) {
|
||||||
|
return roundedBorder.getColor();
|
||||||
|
}
|
||||||
|
return fallback;
|
||||||
|
}
|
||||||
|
|
||||||
public static void apply(OACFrame frame) {
|
public static void apply(OACFrame frame) {
|
||||||
DesignFlags designFlags;
|
DesignFlags designFlags;
|
||||||
|
|
||||||
@@ -122,8 +215,50 @@ public class DesignManager {
|
|||||||
frame.getContentPane().setBackground(designFlags.background().getColor());
|
frame.getContentPane().setBackground(designFlags.background().getColor());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
applyTree(frame.getRootPane());
|
||||||
|
applyTree(frame.getLayeredPane());
|
||||||
|
installAutoApply(frame.getRootPane());
|
||||||
|
installAutoApply(frame.getLayeredPane());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static DesignFlags resolveFlags(Class<?> type) {
|
||||||
|
Class<?> current = type;
|
||||||
|
while (current != null) {
|
||||||
|
DesignFlags flags = globalDesign.getElements().get(current);
|
||||||
|
if (flags != null) {
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
current = current.getSuperclass();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void applyTree(Component component) {
|
||||||
|
if (component instanceof OACComponent oacComponent) {
|
||||||
|
oacComponent.initDesign();
|
||||||
|
}
|
||||||
|
if (component instanceof Container container) {
|
||||||
|
installAutoApply(container);
|
||||||
|
for (Component child : container.getComponents()) {
|
||||||
|
applyTree(child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void installAutoApply(Container container) {
|
||||||
|
if (!(container instanceof JComponent jComponent)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (Boolean.TRUE.equals(jComponent.getClientProperty(OAC_LISTENER_PROPERTY))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
container.addContainerListener(new ContainerAdapter() {
|
||||||
|
@Override
|
||||||
|
public void componentAdded(ContainerEvent e) {
|
||||||
|
applyTree(e.getChild());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
jComponent.putClientProperty(OAC_LISTENER_PROPERTY, Boolean.TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void registerDesign(Design design) {
|
public void registerDesign(Design design) {
|
||||||
|
|||||||
@@ -5,13 +5,11 @@
|
|||||||
package org.openautonomousconnection.oacswing.test;
|
package org.openautonomousconnection.oacswing.test;
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.openautonomousconnection.oacswing.component.OACButton;
|
import org.openautonomousconnection.oacswing.component.*;
|
||||||
import org.openautonomousconnection.oacswing.component.OACFrame;
|
|
||||||
import org.openautonomousconnection.oacswing.component.OACPanel;
|
|
||||||
import org.openautonomousconnection.oacswing.component.OACTextField;
|
|
||||||
import org.openautonomousconnection.oacswing.component.design.Design;
|
import org.openautonomousconnection.oacswing.component.design.Design;
|
||||||
import org.openautonomousconnection.oacswing.component.design.DesignManager;
|
import org.openautonomousconnection.oacswing.component.design.DesignManager;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
|
|
||||||
public class CustomizedTests {
|
public class CustomizedTests {
|
||||||
@@ -29,9 +27,19 @@ public class CustomizedTests {
|
|||||||
|
|
||||||
navBar.add(textField, BorderLayout.CENTER);
|
navBar.add(textField, BorderLayout.CENTER);
|
||||||
frame.getContentPane().add(navBar, BorderLayout.NORTH);
|
frame.getContentPane().add(navBar, BorderLayout.NORTH);
|
||||||
|
frame.add(navBar);
|
||||||
frame.setVisible(true);
|
frame.setVisible(true);
|
||||||
|
Object[] options = {"Continue", "Cancel"};
|
||||||
wait(15000);
|
OACOptionPane.showOptionDialog(
|
||||||
|
frame,
|
||||||
|
"You never connected to this INS before!\n" +
|
||||||
|
"Fingerprint: " + "caFingerprint" + "\nDo you want to connect?",
|
||||||
|
"INS Connection",
|
||||||
|
OACOptionPane.YES_NO_OPTION,
|
||||||
|
OACOptionPane.INFORMATION_MESSAGE,
|
||||||
|
null,
|
||||||
|
options,
|
||||||
|
options[0]
|
||||||
|
); wait(15000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user