The size of color palette in JColorChooser/Swatches is very small, also the colors looks similar around a palette.
For my use I need to increase their size as well change the color variation. How to do this?
The size of color palette in JColorChooser/Swatches is very small, also the colors looks similar around a palette.
For my use I need to increase their size as well change the color variation. How to do this?
[JColorChooser][1]
is compound JComponent
you can to display/use only desired part of JColorChooser
for easier workaround to use SwingUtils by @Darryl Burke
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.colorchooser.AbstractColorChooserPanel;
import javax.swing.event.*;
import javax.swing.plaf.metal.MetalComboBoxIcon;
public class DropDownComponent2 {
private JWindow _window;
private boolean _windowShouldBeShown = false;
private JComponent _component;
private AbstractButton _button;
private JFrame _ownerFrame;
public DropDownComponent2(JFrame ownerFrame, JComponent component, AbstractButton button) {
_ownerFrame = ownerFrame;
_component = component;
_button = button;
_button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
_window.setVisible(false);
Point pt = _button.getLocationOnScreen();
pt.translate(0, _button.getHeight());
_window.setLocation(pt);
showWindow();
_windowShouldBeShown = true;
Window[] wins = Window.getWindows();
System.out.println(wins.length);
}
});
_button.addAncestorListener(new AncestorListener() {
@Override
public void ancestorAdded(AncestorEvent event) {
_window.setVisible(false);
}
@Override
public void ancestorRemoved(AncestorEvent event) {
_window.setVisible(false);
}
@Override
public void ancestorMoved(AncestorEvent event) {
if (event.getSource() != _window) {
System.out.println("Ansestor moved");
_window.setVisible(false);
}
}
});
Toolkit.getDefaultToolkit().addAWTEventListener(
new AWTEventListener() {
@Override
public void eventDispatched(AWTEvent event) {
if (event.getID() == MouseEvent.MOUSE_CLICKED) {
if (!_window.getBounds().contains(MouseInfo.getPointerInfo().getLocation())) {
if (_windowShouldBeShown) {
_windowShouldBeShown = false;
} else {
_window.setVisible(false);
}
}
}
}
}, AWTEvent.MOUSE_EVENT_MASK);
_window = new JWindow(_ownerFrame);
_window.getContentPane().add(component);
_window.addWindowFocusListener(new WindowAdapter() {
@Override
public void windowLostFocus(WindowEvent evt) {
System.out.println("window lost focus");
_window.setVisible(false);
}
});
_window.pack();
}
private Rectangle getScreenRect() {
return new Rectangle(java.awt.Toolkit.getDefaultToolkit().getScreenSize());
}
public void showWindow() {
Rectangle screenRect = getScreenRect();
Rectangle windowRect = _window.getBounds();
int sx1 = screenRect.x;
int sx2 = screenRect.x + screenRect.width;
int sy1 = screenRect.y;
int sy2 = screenRect.y + screenRect.height;
int wx1 = windowRect.x;
int wx2 = windowRect.x + windowRect.width;
int wy1 = windowRect.y;
int wy2 = windowRect.y + windowRect.height;
if (wx2 > sx2) {
_window.setLocation(wx1 - (wx2 - sx2), _window.getY());
}
if (wx1 < sx1) {
_window.setLocation(0, _window.getY());
}
if (wy2 > sy2) {
_window.setLocation(_window.getX(), wy1 - (wy2 - wy1));
}
if (wy2 < sy1) {
_window.setLocation(_window.getX(), 0);
}
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
_window.setVisible(true);
}
});
}
public void hideWindow() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
_window.setVisible(false);
}
});
}
}
class DropDownFrame extends JFrame {
private static final long serialVersionUID = 1L;
private JButton _button;
private JColorChooser _colorChooser;
private DropDownComponent2 _dropDown;
private JWindow _window;
public DropDownFrame() {
_colorChooser = new JColorChooser();
_colorChooser.setPreviewPanel(new JPanel());
_colorChooser.setColor(Color.RED);
// Remove panels other than Swatches
AbstractColorChooserPanel[] panels = _colorChooser.getChooserPanels();
for (int i = 0; i < panels.length; i++) {
if (!panels[i].getDisplayName().equals("Swatches")) {
_colorChooser.removeChooserPanel(panels[i]);
} else {
JPanel panel = panels[i];
System.out.println(panel.getComponentCount()); // 1
System.out.println(panel.getPreferredSize()); //width=424,height=112
System.out.println(panel.getLayout()); //FlowLayout[hgap=5,vgap=5,align=center]
}
}
_colorChooser.getSelectionModel().addChangeListener(new ChangeListener() {
@Override // ### I think the key point is there
public void stateChanged(ChangeEvent e) {
_button.setForeground(_colorChooser.getColor());
_dropDown.hideWindow();
}
});
_button = new JButton("Show JWindow");
_button.setIcon(new MetalComboBoxIcon());
_button.setHorizontalTextPosition(SwingConstants.LEFT);
this.getContentPane().add(_button);
_dropDown = new DropDownComponent2(DropDownFrame.this, _colorChooser, _button);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setVisible(true);
}
public static void main(String args[]) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
DropDownFrame dropDownFrame = new DropDownFrame();
}
});
}
}
The size of the "swatches" is controlled by two UI properties, so you can adjust it as needed (default value being 10):
Customizing the palette itself requires a custom subclass of AbstractColorChooserPanel, mainly a c&p job (because it's package private) of DefaultSwatchChooserPanel in javx.swing.colorchooser. Then replace the default with your custom panel, something along the lines