How do I programmaticaly update the color of N JComponents (background and foreground), by changing a Color variable c ?
Example:
I have 10 JButton and 5 JCheckbox.
I have the variable:
Color mainColor = Color.RED;
I set all backgrounds and foregrounds to mainColor.
Now if I want all of them to be blue, mainColor = Color.BLUE will not work.
Normally I would do something like mainColor.setRgb(0,0,255), but for whatever reason, Color does not allow this.
So what can I do? Other workarounds are appreciated as well.
The components are spread out accross a lot of panels and frames and some appear dynamically so I'd rather not keep a list.
Also not all of them require both foreground and background to be painted.
You have to reset the color on all the JComponents. For simplicity, you could create a helper method that does it for you.
void changeMainColor(Color c){
this.mainColor = c;
for (JComponents jc : this.myComponentsList){
jc.setForeground(c);
jc.setBackground(c);
}
}
EDIT
If you do not want to keep a list of components manually, use the Observer pattern:
For even greater abstraction, use Publisher/Subscriber pattern. Everytime you change the main color you sill "publish" the fact. All the components that are registered as "subscribers" to that event, will then be able to use the information provided (the color) in the event to do what they want (change background etc..)
I would suggest reading about them in the gang of four book (Design Patterns: Elements of Reusable Object-Oriented Software), but some quick references are below:
https://sourcemaking.com/design_patterns/observer and
https://abdulapopoola.com/2013/03/12/design-patterns-pub-sub-explained/
Ugly style : subclass java.awt.Color, delegating to a real Color instance with a mutator for the delegate.
Related
I'm currently working on redoing the GUI of a project which uses the component GridControl which is an extension of gridView, found here:
http://techpubs.borland.com/books/jbuilder/jbuilder2/jbuilder/reference/borland.jbcl.control.GridControl.html
I'm not allowed to change the components used so I have to find a way to do this with gridControl, however I'm relatively new at programming, so don't really know what I'm doing. I've been asked to get the alternative rows of the table to be grey. I can't find a specific function of the component which caters for this like JTabel seems to have so I was hoping that someone would be able to help. The only one which seems related is .setBackground which seems to only affect the full table.
Thanks very much in advance.
Check out THIS link. It has a mention of this function:
public Color getBackgroundColor(..):callback method automatically invoked by the grid to retrieve the background color for each grid's cell. A programmer can override this method to specify distinct colors for grid's cells.
If the method is not overridden, then rows are colored alternatively with two different colors: one color is defined through ClientSettings.GRID_CELL_BACKGROUND attribute and the other color is slightly different from the first one, defined through getDeltaColor() method.
now, the defaule colour values for ClientSettings.GRID_CELL_BACKGROUND is rgb (238,238,238) which is grey, and for deltaColor is rgb (235,235,235) also grey.
so, the cells should all be grey, unless there's been an override for the function public Color getBackgroundColor(..), something like this:
public Color getBackgroundColor(int row,String attributedName,Object value) {
return new Color(255,255,255); /*for all cells to be White*/
}
In order to make alternate rows grey (assuming the other color white) find the override of the above method and change its body to get your required colours, for eg:
public Color getBackgroundColor(int row,String attributedName,Object value) {
if (row%2==0)
return new Color(255,255,255); /*sets White background for even rows*/
else
return new Color(238,238,238); /*sets Grey background for odd rows*/
}
I'm relatively new at programming, so don't really know what I'm doing hmm.. there are a lot of help/examples available online. you need to learn to search intelligently and follow it up with some background theory to learn on your own.. and you'll survive (for now).
I would like to display multiple texts/scores on my stage. This tutorial suggested SpriteBatch, however, the issue is that these texts won’t fade out (not actor). Certain posts suggested use table, but the issue is that I can’t set texts' position on stage. Is there any other way to display texts as an actor on stage without using table?
Thanks in advance.
Zi
You can create a subclass of actor and draw text as you like in it's overridden draw method.
Just don't forget to set alpha before drawing using setColor method. The value of alpha will be available as a parameter for draw.
You then can fade it the way you want.
Good luck.
I understand that 'fluid' isn't the best description, but that's how I imagine the green that lays inside a progress bar.
I was just wondering if it was possible to just see the green 'fluid' from the progress bar, and not the container that hold the 'fluid'.
The purpose of this is to make artwork under the progress bar that would hold the green 'fluid', rather then the system's default UI holding this fluid.
EDIT:
This is a photo of the current progress bar in question:
The JFrame this is on is INVISIBLE, so all you can see is this bar.
I would like to know if it is possible to remove the GREY from around the JProgressBar and just display the green.
By fluid, you may mean the paint used by a BasicProgressBarUI in its implementation of paintDeterminate(). The UI delegate fills all of boxRect with ProgressBar.background and some fraction of boxRect with ProgressBar.foreground. You can
Change the color via the UIManager, as discussed here, but the delegate is not obligated to use your setting.
Implementnt your own ProgressBarUI, as suggested here.
http://docs.oracle.com/javase/6/docs/api/javax/swing/JProgressBar.html#paintBorder
you should use setBorderPainted to remove the border, I guess that's what you want.
I know this is an old question, but found it using google and I'm trying to do exactly the same thing. I found setting the background to transparent works perfectly, at least with the Nimbus L&F, haven't tested this with others.
progress.setBackground (new Color (0, 0, 0, 0));
I'm doing a simulator project that tests several A* based algorithms and show how they work and their results.
The algorithms are all multi-agent and run on a grid map environment.
I used a JPanel for the grid which contains a two dimensional array of Cells where each Cell is a custom class that extends the Component class and use the paint method to draw the stuff i need inside each cell.
For the drawing inside the cell I use method such as Graphics.fillRect or Graphics.drawImage to fill each cell with a certain color or icon).
I'm using a special Icon for the start position and goal position of every agent on the grid.
My problem is that I want to be able to draw more than one item on the same cell.
For example I want to be able to show the path of one of the agents by painting the cells along the path in a special color and the path might go through a start position of a different agent, so I want to be able to fill the cell with the color and have an icon drawn on top.
In another example I want to be able to mix two colors using alpha blending.
If I use graphics.fillRect() with one color that has alpha and then use it again with a different color with alpha value it won't work since the last fillRect() will override the first call.
Is there a way I can achieve what I need using the same Cell Component I created or should I implement it differently?
Perhaps there is a better solution to this problem?
I would really appreciate any advice on this matter.
If you draw a rectangle with 50% alpha and then draw another one, the second one will override it instead of blending with it.
It depends on the mode. This convenient utility shows the result of blending different colors using the modes defined in AlphaComposite. The available source code may offer some insights for your project.
Addendum:
the stuff I was trying to composite was on the same Component.
The example cited does exactly this, as does this example. If AlphaComposite does not meet your requirements, you can always vary hue, saturation and/or value; this example composes a color table based on saturation.
I have an application that uses disabled JTextFields in several places which are intended to be transparent - allowing the background to show through instead of the text field's normal background.
When running the new Nimbus LAF these fields are opaque (despite setting setOpaque(false)), and my UI is broken. It's as if the LAF is ignoring the opaque property. Setting a background color explicitly is both difficult in several places, and less than optimal due to background images actually doesn't work - it still paints it's LAF default background over the top, leaving a border-like appearance (the splash screen below has the background explicitly set to match the image).
Any ideas on how I can get Nimbus to not paint the background for a JTextField?
Note: I need a JTextField, rather than a JLabel, because I need the thread-safe setText(), and wrapping capability.
Note: My fallback position is to continue using the system LAF, but Nimbus does look substantially better.
See example images below.
Conclusions
The surprise at this behavior is due to a misinterpretation of what setOpaque() is meant to do - from the Nimbus bug report:
This is a problem the the orginal design of Swing and how it has been confusing for years. The issue is setOpaque(false) has had a side effect in exiting LAFs which is that of hiding the background which is not really what it is ment for. It is ment to say that the component my have transparent parts and swing should paint the parent component behind it.
It's unfortunate that the Nimbus components also appear not to honor setBackground(null) which would otherwise be the recommended way to stop the background painting. Setting a fully transparent background seems unintuitive to me.
In my opinion, setOpaque()/isOpaque() is a faulty public API choice which should have been only:
public boolean isFullyOpaque();
I say this, because isOpaque()==true is a contract with Swing that the component subclass will take responsibility for painting it's entire background - which means the parent can skip painting that region if it wants (which is an important performance enhancement). Something external cannot directly change this contract (legitimately), whose fulfillment may be coded into the component.
So the opacity of the component should not have been settable using setOpaque(). Instead something like setBackground(null) should cause many components to "not have a background" and therefore become not fully opaque. By way of example, in an ideal world most components should have an isOpaque() that looks like this:
public boolean isOpaque() { return (background!=null); }
I ran into this same issue last week using JTextPane. The setOpaque() method works as expected when using any look and feel other than nimbus. Apparently, the nimbus look and feel changes the behaviour we have come to expect with setOpaque() for many Components. Depending on how you look at it, it can be considered a bug. Check the comments on this sun bugid:
nimbus opaque bug
The workaround that worked for me was:
myPane.setOpaque(false); // added by OP
myPane.setBorder(BorderFactory.createEmptyBorder());
myPane.setBackground(new Color(0,0,0,0));
Note from OP: I also had to ensure setOpaque(false) for JTextField so that the parent background was painted - just wanted to mention this for others who follow in case they had experimented with setOpaque(true), as I had.
Hey there Software Monkey.
mmhh what about installing UI's subclasses replacement that actually respect the setOpaque behavior.
I think it is something like setUI or something like that.
You could grab the source code of the nimbus and see what's broken there ( if it is there ) , subclass it and install the "fixed" one.
Yours sound quite intersting, do you have any screenshot we can see?
From the javadoc
public void setBackground(Color bg)
Sets the background color of this component. The background color is
used only if the component is opaque,
and only by subclasses of JComponent
or ComponentUI implementations. Direct
subclasses of JComponent must override
paintComponent to honor this property.
It is up to the look and feel to honor this property, some may choose
to ignore it.
I think the question is how to interpret "opaque" and "background".
For a JTextfield there is the question: "what visible parts are the background?". I'd define "background" as the parts of the bounding rectangle, that are not drawn by the component.
For a "round" button, e.g., this will be the corners outside the circle.
Therefor I'd say a JTextfield has no visible background! It has a rectangular shape and what you are the taking as background is not the field's background but the field's canvas.
Rebuttal from OP
This is an interesting enough idea to be worth responding to in the answer for future viewers (as opposed to in comments).
I have to disagree. I would argue that the part of the component outside the border is not part of the component - it's outside the component. A field with rounded corners is, of necessity, non-opaque, in that it cannot be responsible for painting it's entire rectangular region - this is a side-effect of all components being rectangular in dimensions.
I think this consideration makes the argument for the existing (and misunderstood) meaning of isOpaque(). It also makes my argument that setOpaque() should not exist and that setBackground(null) should cause the component to not paint a background.
I would put forth that the background of a text field is indeed the color of the region inside it's borders, and I don't think you will find very many people to dispute that as an intuitive conclusion - therefore having background apply to that region obeys the rule of least surprise for the API user.