Changing colour of all buttons in netbeans - java

I've got 4 Buttons on my Form and a menu bar with an option to change their colours. In my code I change colour of each one individually, like this:
jButton1.setBackground(Color.cyan);
jButton2.setBackground(Color.cyan);
jButton3.setBackground(Color.cyan);
jButton4.setBackground(Color.cyan);
Which isn't a problem right now but might become one if I add more of them. So is there a way to change the colour of all present buttons at once?

You can try to create an array of jbuttons such as:
JButton[] buttonsArr = new JButton[4];
and then you can loop on the items and set color of text for all of them.
Such as:
for(int i = 0;i < 4;i++){
buttonsArr[i] = new JButton(String.valueOf(i));
// Or you can add the color such as
buttonsArr[i].setBackground(Color.cyan);
}
Another solution is to declare a Color Variable and use it as a global variable or as Enum such as:
Color globalColor = new Color(187, 157, 177);
jButton1.setBackground(globalColor);
jButton2.setBackground(globalColor);
jButton3.setBackground(globalColor);
jButton4.setBackground(globalColor);
And whenever you need to change it you can change it easily by changing it is value.
Check those links for more help:
Link_1 & Link_2

Assume you have this interface
and you want to change color of all buttons to any other color you want.
My recommendation is to create a recursive method similar to DFS algorithm that can scan all components in your interface and find all buttons even if each button is a child for another component.
Here is an example:-
private List<Component> getAllButtons(Component[] components) {
List<Component> buttons = new LinkedList();
for (Component component: components) {
if (component instanceof JButton) {
buttons.add(component);
} else {
JComponent jComponent = ((JComponent) component);
buttons.addAll(getAllButtons(jComponent.getComponents()));
}
}
return buttons;
}
This method needs to pass the parents components of the interface and it will scan each component either it's a button or not, if it's a button! it will be added to the list, if not! it will get the children's of this component and scan each one recursively until get all buttons.
Now, to call this method, you should add listeners to Button Color items. For me, i prefer to create a one action listener for all these items.
private void actionPerformed(java.awt.event.ActionEvent evt) {
String colorName = ((JMenuItem) evt.getSource()).getText();
Color color = null;
if (colorName.equals("red")) {
color = Color.RED;
} else if (colorName.equals("green")) {
color = Color.GREEN;
} else if (colorName.equals("blue")) {
color = Color.BLUE;
} else if (colorName.equals("cyan")) {
color = Color.CYAN;
}
List<Component> buttons = getAllButtons(this.getComponents());
for (Component component : buttons) {
component.setBackground(color);
}
}

Related

Why doesn't my Combobox update its color properly?

I am implementing a dark mode into my program and everything works just fine, except a Combobox, which doesn't want to change its color as I want.
(source: bilder-upload.eu)
So as you can see, the "popup" of the Combobox changes the color just fine, but the Combobox itself doesn't. Also the Foreground color of the Combobox changes, but the background not.
I guess, the Look and Feel might cause the issue.
In my main-class:
UIManager.setLookAndFeel( UIManager.getSystemLookAndFeelClassName() );
Where I change to Darkmode:
TeamInterface.userFilterComboBox.setBackground( darkBackgroundColor );
TeamInterface.userFilterComboBox.setForeground( fontColor );
SwingUtilities.updateComponentTreeUI( TeamInterface.userFilterComboBox );
I have to use the updateComponentTreeUI-Method, because otherwise the "popup" also remains white.
If I remove the look and feel in my main-class, the combobox looks good,as you can see in this picture,
(source: bilder-upload.eu)
but I doesn't want to get rid of the system look and feel, so I tried to manually edit the UI of the combobox to metal with this code :
userFilterComboBox.setUI( new MetalComboBoxUI() );
but.. the result is just awful, even thoe theoretically (at leats thats what I think) it should look the same as without look and feel
(source: bilder-upload.eu)
The Combobox not is a component only to the background and the foreground but is the complex component.
An example:JComboBox is composed to:
ArrowButton
List of itme
Border (and it have a color)
the item selected
So for change all you can add inside your UIManager, all constant or you can define a new UIComponent.
So an PersonalComboBoxUI can the following:
/**
* #contributor https://github.com/vincenzopalazzo
*/
public class PersonalComboBoxUI extends BasicComboBoxUI {
public static ComponentUI createUI (JComponent c) {
return new PersonalComboBoxUI ();
}
#Override
public void installUI (JComponent c) {
super.installUI (c);
JComboBox<?> comboBox = (JComboBox<?>) c;
comboBox.setBackground (UIManager.getColor ("ComboBox.background"));
comboBox.setForeground (UIManager.getColor ("ComboBox.foreground"));
comboBox.setBorder (UIManager.getBorder ("ComboBox.border"));
comboBox.setLightWeightPopupEnabled (true);
}
#Override
protected JButton createArrowButton () {
Icon icon = UIManager.getIcon ("ComboBox.buttonIcon");
JButton button;
if (icon != null) {
button = new JButton (icon);
}
else {
button = new BasicArrowButton (SwingConstants.SOUTH);
}
button.setOpaque (true);
button.setBackground (UIManager.getColor ("ComboBox.buttonBackground"));
button.setBorder (BorderFactory.createLineBorder(Color.black));
return button;
}
#Override
protected ListCellRenderer createRenderer() {
return new MaterialComboBoxRenderer();
}
}
You should be defined also the PersonalComboBoxRenderer
/**
* #contributor https://github.com/vincenzopalazzo
*/
public class PersonalComboBoxRenderer extends BasicComboBoxRenderer {
#Override
public Component getListCellRendererComponent (JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
JComponent component = (JComponent) super.getListCellRendererComponent (list, value, index, isSelected, cellHasFocus);
component.setBorder (BorderFactory.createEmptyBorder (5, 5, 5, 5));
component.setForeground (UIManager.getColor ("ComboBox.foreground"));
component.setBackground (isSelected || cellHasFocus ?
UIManager.getColor("ComboBox.selectedInDropDownBackground") :
UIManager.getColor("ComboBox.background"));
return component;
}
}
ps: in this case, I'm using the UIManager.put("ComboBox.background", COLOR) for add and stratification inside the JComponent.
So I want to add two information regarding if you using the personal color inside the UIManager or the PersonalComboBoxUI the color should be defined with this code
Color PINK_400 = new ColorUIResource (236, 64, 122);
because when you go to remove look and feel the color couldn't remove but if you used ColorUIResource the look and feel should be removed correctly.
To finish, if you do not have needed the default look and feel, I want to suggest you use a library.
The material-UI-swing has a system theming for creating the personal timing in your app and the all theme is personalizable.
This is the repo vincenzoapalazzo/material-ui-swing and atarw/material-ui-swing are the same repository and the same developer so, the vincenzopalazzo/material-us-swing is the developer branch, an contains more fix and test.
An example of the library is
.
Ps: I am the designer of the MaterialTheming System.

Color (Alpha) changes by mouseover till tooltip appears

I currently try to add some instances JCheckBox with ToolTips. These ToolTips change whenever the user selects or unselect the JCheckBox (via ItemListener). But: Everytime I go over the JCheckbox it changes the Color (the Alpha) so it becomes less transparent, so it seems like the Alpha of the Background changes. It changes back as soon as I wait for the ToolTip, but this still annoys me a bit.
Here is my code:
public class MyBox extends JCheckBox {
private final String onSelected;
private final String onNotSelected;
private int index;
public MyBox(int index){
super();
this.setDoubleBuffered(true);
this.index = index;
this.onSelected = "ABC";
this.onNotSelected = "DEF";
this.setToolTipText(this.onNotSelected);
super.setOpaque(true);
this.setBackground(new Color(0, 0, 255, 80));
Dimension size = new Dimension(10,10);
this.setHorizontalAlignment(SwingConstants.CENTER);
}
public int getIndex(){
return this.index;
}
public void setTooltipFor(boolean selected){
String setto = selected ? onSelected : onNotSelected;
this.setToolTipText(setto);
}
public void disableEditing(){
this.setEnabled(false);
}
}
And
public class MyListener implements ItemListener{
public MyListener(){
}
#Override
public void itemStateChanged(ItemEvent ie) {
MyBox box =((MyBox) ie.getItemSelectable());
int index = box.getIndex();
if(ie.getStateChange() == ItemEvent.SELECTED){
box.setTooltipFor(true);
}
else{
box.setTooltipFor(false);
}
}
}
Of the Listener is added in another class (adding and changing works). The problem remains: Why is the alpha changing (the color becomes more opaque and darker) and how can I avoid that?
But: Everytime I go over the JCheckbox it changes the Color (the Alpha) so it becomes less transparent
Yes, Swing does not know how to handle transparent colors properly because you are breaking the painting rules.
Check out Backgrounds With Transparency for more information and solutions. You can either:
Do the custom painting of the background yourself
Use the provided AlphaContainer class to do the painting for you

GridLayout Representing an ArrayList of JLabels issue

I'm looking for a bit of help with a problem I'm having. I am creating a GridLayout on my GUI and in each Grid there will be a JLabel. Along side this I have an ArrayList which contains images which will be displayed in each Grid.
What I am trying to do is when I click a specific grid, it will add an image from the ArrayList and place it in the grid position. What I would like is have a left click to add the item in the ArrayList and a right click to remove the item in the list.
The ArrayList and GUI code are in different classes and the ArrayList is implemented in the main method. I have tried to no avail, I cannot seem to get the grids to represent the list.
Basically I need a GridLayout to give a visual representation of an ArrayList, that can be manipulated with mouse interaction
Can anyone point me in the right direction?
Code for the Grids:
for (int i = 0; i < 12; i++)
{
JLabel assetLabel = new JLabel("Test"+(i+1));
System.out.println("assetLabel"+(i));
assetLabel.addMouseListener(new ParcelInfo(i));
assetLabel.setBackground(Color.WHITE);
assetLabel.setOpaque(true);
assetGrid.add(assetLabel);
}
Code for the items I need in the JLabel:
public class test
{
private ImageIcon img;
test(ImageIcon i)
{
this.img=i;
}
}
This is how you define a Listener for it.
public List<Image> arrayList = new ArrayList<>();
public OtherClassWithArray foo = new OtherClassWithArray();
jLabel.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
if(e.getButton() == MouseEvent.BUTTON1) // left click
jLabel.setIcon(arrayList.get(xyz)); // access arraylist here
// jLabel.setIcon(foo.getArrayList.get(xyz); // access arrayList from other class
else // right click
// do smth here
}
});

JColorChooser: Save/restore recent colors in Swatches panel

I am using a JColorchooser at various places in an application. There can be multiple instances of the panel that can invoke a JColorChooser.
The "Swatches" panel in the chooser has an area of "recent" colors, which only persists within each instance of JColorChooser. I would like to (a) have the same "recent" colors in all my choosers in my application, and (b) to save the colors to disk so that these colors survive close and restart of the application.
(At least (a) could be solved by using the same single chooser instance all over the whole app, but that apears cumbersome because I would need to be very careful with attached changelisteners, and adding/removing the chooser panel to/from various dialogs.)
I did not find any method that lets me set (restore) these "recent" colors in the chooser panel. So to me, it appears that the only ways of achieving this would be:
serialize and save / restore the whole chooser (chooser panel?)
or
create my own chooser panel from scratch
Is this correct, or am I missing something?
BTW: I would also like to detect a double click in the chooser, but it seems hard to find the right place to attach my mouse listener to. Do I really need to dig into the internal structure of the chooser panel to do this? (No, it does not work to detect a second click on the same color, because the change listener only fires if a different color is clicked.)
As you noticed, there is no public api to access the recent colors in the DefaultSwatchChooserPanel, even the panel itself isn't accessible.
As you'll need some logic/bean which holds and resets the recent colors anyway (plus the extended mouse interaction), rolling your own is the way to go. For some guidance, have a look at the implementation of the swatch panel (cough ... c&p what you need and modify what you don't). Basically, something like
// a bean that keeps track of the colors
public static class ColorTracker extends AbstractBean {
private List<Color> colors = new ArrayList<>();
public void addColor(Color color) {
List<Color> old = getColors();
colors.add(0, color);
firePropertyChange("colors", old, getColors());
}
public void setColors(List<Color> colors) {
List<Color> old = getColors();
this.colors = new ArrayList<>(colors);
firePropertyChange("colors", old, getColors());
}
public List<Color> getColors() {
return new ArrayList<>(colors);
}
}
// a custom SwatchChooserPanel which takes and listens to the tracker changes
public class MySwatchChooserPanel ... {
ColorTracker tracker;
public void setColorTracker(....) {
// uninstall old tracker
....
// install new tracker
this.tracker = tracker;
if (tracker != null)
tracker.addPropertyChangeListener(.... );
updateRecentSwatchPanel()
}
/**
* A method updating the recent colors in the swatchPanel
* This is called whenever necessary, specifically after building the panel,
* on changes of the tracker, from the mouseListener
*/
protected void updateRecentSwatchPanel() {
if (recentSwatchPanel == null) return;
recentSwatchPanel.setMostRecentColors(tracker != null ? tracker.getColors() : null);
}
// the mouseListener which updates the tracker and triggers the doubleClickAction
// if available
class MainSwatchListener extends MouseAdapter implements Serializable {
#Override
public void mousePressed(MouseEvent e) {
if (!isEnabled())
return;
if (e.getClickCount() == 2) {
handleDoubleClick(e);
return;
}
Color color = swatchPanel.getColorForLocation(e.getX(), e.getY());
setSelectedColor(color);
if (tracker != null) {
tracker.addColor(color);
} else {
recentSwatchPanel.setMostRecentColor(color);
}
}
/**
* #param e
*/
private void handleDoubleClick(MouseEvent e) {
if (action != null) {
action.actionPerformed(null);
}
}
}
}
// client code can install the custom panel on a JFileChooser, passing in a tracker
private JColorChooser createChooser(ColorTracker tracker) {
JColorChooser chooser = new JColorChooser();
List<AbstractColorChooserPanel> choosers =
new ArrayList<>(Arrays.asList(chooser.getChooserPanels()));
choosers.remove(0);
MySwatchChooserPanel swatch = new MySwatchChooserPanel();
swatch.setColorTracker(tracker);
swatch.setAction(doubleClickAction);
choosers.add(0, swatch);
chooser.setChooserPanels(choosers.toArray(new AbstractColorChooserPanel[0]));
return chooser;
}
As to doubleClick handling: enhance the swatchChooser to take an action and invoke that action from the mouseListener as appropriate.
You can use the JColorChooser.createDialog method - one of the parameters is a JColorChooser. Use a static instance of the JColorChooser and make it the Dialog modal - that way, only one color chooser is displayed at a time.
The createDialog method also takes ActionListeners as parameters for the OK and Cancel button. Thus, don't really have to manage listeners. Of course, this doesn't persist the recent colors across invocations of the app, just persists recent colors in the current app.
Here's a workaround using reflection - it will work provided the underlying implementation doesn't change. Assuming you have a JColorChooser, add your recent colors to it like this:
final JColorChooser chooser = new JColorChooser(Color.white);
for (AbstractColorChooserPanel p : chooser.getChooserPanels()) {
if (p.getClass().getSimpleName().equals("DefaultSwatchChooserPanel")) {
Field recentPanelField = p.getClass().getDeclaredField("recentSwatchPanel");
recentPanelField.setAccessible(true);
Object recentPanel = recentPanelField.get(p);
Method recentColorMethod = recentPanel.getClass().getMethod("setMostRecentColor", Color.class);
recentColorMethod.setAccessible(true);
recentColorMethod.invoke(recentPanel, Color.BLACK);
recentColorMethod.invoke(recentPanel, Color.RED);
//add more colors as desired
break;
}
}

expand and collapse icons

As you can see from the images below the expand and collapse icons are gray, as is the row selection highlight. This causes you to not see the expand or collapse icon (Note: Not the folder icon) when the row is highlighted, I want to have a white expand or collapse icon for the row that is selected. How can that be done?
Something else that would also be cool is, to have the expand and collapse icons completely hidden until the JTree gains focus. like windows 7's tree.
Google says -according to this post: http://www.exampledepot.com/egs/javax.swing.tree/DefIcons.html - :
// Retrieve the three icons
Icon leafIcon = new ImageIcon("leaf.gif");
Icon openIcon = new ImageIcon("open.gif");
Icon closedIcon = new ImageIcon("closed.gif");
// Create tree
JTree tree = new JTree();
// Update only one tree instance
DefaultTreeCellRenderer renderer = (DefaultTreeCellRenderer)tree.getCellRenderer();
renderer.setLeafIcon(leafIcon);
renderer.setClosedIcon(closedIcon);
renderer.setOpenIcon(openIcon);
// Remove the icons
renderer.setLeafIcon(null);
renderer.setClosedIcon(null);
renderer.setOpenIcon(null);
// Change defaults so that all new tree components will have new icons
UIManager.put("Tree.leafIcon", leafIcon);
UIManager.put("Tree.openIcon", openIcon);
UIManager.put("Tree.closedIcon", closedIcon);
// Create tree with new icons
tree = new JTree();
// Update row height based on new icons;
Certainly, I'm not sure if you can modify only the color of the images on-the-go. But you can always create new icons, right?
You can try this. You should note however to get this to work, I had to override setUI on the tree to only allow my TreeUI.
private class IconTreeUI extends BasicTreeUI {
private Icon collapseIcon = null;
private Icon expandIcon = null;
#Override
public Icon getCollapsedIcon() {
if (collapseIcon == null) {
collapseIcon = new ImageIcon(yourCollapseImageHere);
}
return collapseIcon;
}
#Override
public Icon getExpandedIcon() {
if (expandIcon == null) {
expandIcon = new ImageIcon(yourExpandImageHere);
}
return expandIcon;
}}

Categories