I have encountered a problem where if I use the main method in the same java file that contains the code for the JFrame which contains a JTable, and where I set the header color to yellow, when I run it , the header will be yellow. However, if I instantiate the JFRame by calling it from other classes, the header will not be yellow but will be the default color instead. Is there any way to ensure that the color stays the same even though I instantiate the JFrame and hence JTable from other classes? Thanks alot! I will be glad to clarify things if I have not explained clearly.
Hi I am sorry for not providing code beforehand. Here it is :
EquityFrame eq= new EquityFrame(file,"Apr2012");
this.dispose();// this code is in another class of a JFrame which will call the constructor of EquityFrame class
Code of EquityFrame class
public EquityFrame(File file, String nameTab){
createAndShowGUI( file, nameTab);
}
private void createAndShowGUI(File file, String nameTab){
//create frame
JTabbedPane tabPane= new JTabbedPane();
//pre-processing
init(file,nameTab);
//adding tabs
tabPane.addTab("Proposal", makeAdminPanel());
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame jf= new JFrame("CGH Equity Program");
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setLayout(new BorderLayout());
jf.add(tabPane,BorderLayout.CENTER);
int w = Toolkit.getDefaultToolkit().getScreenSize().width;
int h = Toolkit.getDefaultToolkit().getScreenSize().height;
jf.setSize(w, h);
jf.setVisible(true);
}
private JPanel makeAdminPanel(){
JPanel jp=new JPanel();
String[] column = {"Job Grade", "Job Title", "Min", "Midpoint", "Max",
"Lowest", "P10", "P25", "Median", "P65", "P75", "P90",
"Highest", "Average"};
String[][] data= getArrayOfValuesForEachJobGrade();
jp.setLayout(new BorderLayout());
JTable jt= new JTable(data,column);
JTableHeader th=jt.getTableHeader();
th.setBackground(java.awt.Color.pink);
th.setEnabled(false);
jt.setTableHeader(th);
jt.setEnabled(false);
jp.add(jt,BorderLayout.CENTER);
JScrollPane scrollPane = new JScrollPane(jt, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
scrollPane.setEnabled(false);
jp.add(scrollPane, BorderLayout.CENTER);
return jp;
}
I will first run the first java file which will create an instance of EquityFrame that will display a tabbedPane with a JTable in it. However, the GUI I get from running the EquityFrame with its own main method is different from the GUI I get from creating an instance of it in another code. If i run it using its own main method, there will be a color change in the header of the table. However, the color remains the default if I run it from the other java class.
If I run it using its main method:
http://tinypic.com/r/2r5yjdj/6
If I run it using other class to call its constructor to generate the JFrame:
http://tinypic.com/r/3523yax/6
Thanks once again for any help rendered! Hope that this sheds more light on my problem.
Be certain to change the UI property before constructing anything that relies on the new value, preferablely before starting the event dispatch thread.
UIManager.put("TableHeader.background", Color.yellow);
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new Application();
}
});
Alternatively, you may be able to adapt the approach shown here in the method applyUI(); it can be invoked in the constructor, as shown, or when the system calls updateUI().
Addendum: Your first image shows a Look & Feel that supports the TableHeader.background UI property. The second image appears to be the Nimbus L&F, which does not support the property.
Is the code which set the color in the definition of your main method? If so, put it in the constructors for the JFrame or JTable instead.
Related
this is my first question on stackoverflow so pls don't be so hard with me (and my English), I'll try my best asking a good question.
The problem is about what the title suggests -> setting the background of a JTextpane (specifically setting it transparent). As the setBackground-method takes a color argument, the way i went was with an alpha value = 0. This leads to the following visual artifacts:
example picture of the visual artifacts when running the code below
I will describe it in detail now, say what i've already tried and then post a minimal example for everyone to be able to recreate the bug easily.
I have a JFrame (myFrame) holding a JPanel (Test()) in which i paint. The background of this JPanel is set to green as you can see in the code. I did this to differ between the background of the TextPane and the actual background of the panel.
We also have a JTextPane inputfield -> which takes user input (it displays what you write). This is held by a JScrollPane scrollpane.
So the Target (meaning what i try to achieve): is a User input field, which is transparent, but still displays the text the user puts in. I tried to achieve this by setting the background of the inputfield and the scrollpane to a transparent color.
I would really appreciate it, if you don't just type something like (you need to setOpague(false) for ....) if you don't know exactly what you're talking about, because i nearly tried everything i can think of and read every post i could find in the internet about the problem. I will post some of them at the end. So...
What i already tried:
The usual way i found while searching for something like "How to make TextPane transparent" was to setOpague(false) at itself as well as the scrollpane and the viewport of the scrollpane. 1. Reading about what the method actually does i don't think that is a proper solution. 2. setting Opague(false) on these three leads to everything being invisible so, that's not good. Packing the frame again after setting the background. Either nothing was fixed or the components became completely invisible.
I also tried: setBackground(null), setting the Background of just the inputfield (just every single component and every possible combination amongst the three (scrollpane, viewport, inputfield)), mixing setOpague(true)/setOpague(false)/setBackground(...) in every way i could think of. Overriding the paintComponent method of the textpane and scrollpane seemed like a good approach, but i did not come very far with it.
So here is the code:
public class Test extends JPanel {
JTextPane inputField = new JTextPane();
JScrollPane scrollpane = new JScrollPane(inputField);
#Override
public void paint(Graphics g) {
super.paint(g);
inputField.setBounds(10,10,100,100);
scrollpane.setBounds(10,10,100,100);
}
public Test(){
this.setOpaque(true);
this.setBackground(Color.GREEN);
inputField.setBounds(10,10,100,100);
scrollpane.setBounds(10,10,100,100);
inputField.setBackground(new Color(0,0,0,0));
scrollpane.setBackground(new Color(0,0,0,0));
scrollpane.getViewport().setBackground(new Color(0,0,0,0));
this.add(scrollpane);
}
public static void main(String[] args) {
JFrame myFrame = new JFrame();
myFrame.add(new Test());
myFrame.pack();
myFrame.setSize(640,480);
myFrame.setPreferredSize(new Dimension(640,480));
myFrame.setVisible(true);
}
}
And here some links to posts I read which describe similar problems:
Java - Transparent JScrollPane
Transparent JEditorPane in a JScrollPane over a background JPanel
setOpaque(true/false); Java
I would really appreciate if someone can help me with the problem or even only suggest me an alternative solution. I'm writing a little chat-program atm for a project for my university and i think transparent message fields are a neat idea. I will try to answer here as fast as i can. Thx in advance.
Do not use transparent color as background - kind of hard to delete with it (e.g. when component is being repaint (and opaque)).
Do not use setBounds (unless using null LayoutManager). In below example I used setPreferredSize but still better to correctly use LayoutManager (I am a bit lazy, and lot of work to do at the moment).
public class Test extends JPanel {
JTextPane inputField = new JTextPane();
JScrollPane scrollpane = new JScrollPane(inputField);
public Test(){
this.setOpaque(true);
this.setBackground(Color.GREEN);
inputField.setPreferredSize(new Dimension(300, 100));
inputField.setOpaque(false);
scrollpane.setOpaque(false);
scrollpane.getViewport().setOpaque(false);
this.add(scrollpane);
}
public static void main(String[] args) {
JFrame myFrame = new JFrame();
myFrame.add(new Test());
myFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
myFrame.setPreferredSize(new Dimension(640,480));
myFrame.pack();
myFrame.setVisible(true);
}
}
The whole code of main should be called on the EDT (e.g. SwingUtilities.invokeLater) since it is manipulating swing components but that is not part of the question (and not that relevant here since setVisible is the last command - components not being displayed while changed).
Your program gave me some errors when launching, occasionally. Make sure to run a swing GUI from the EDT (invokeLater()).
The line that is causing your issue is:
scrollpane.getViewport().setBackground(new Color(0,0,0,0));
Also - is there some reason you are setting bounds manually instead of using a layout manager?
Maybe I didn't understand your question, or you want to have an image in the background - but could you not just set the color of your text area to be the same color as your JPanel?
import java.awt.Color;
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
public class Test extends JPanel {
JTextPane inputField = new JTextPane();
JScrollPane scrollpane = new JScrollPane(inputField);
public Test(){
this.setBackground(Color.GREEN);
scrollpane.setPreferredSize(new Dimension(300, 300));
inputField.setBackground(Color.GREEN);
this.add(scrollpane);
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame myFrame = new JFrame();
myFrame.add(new Test());
myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
myFrame.setPreferredSize(new Dimension(640,480));
myFrame.pack();
myFrame.setVisible(true);
}
});
}
}
I have previously used Java's KeyListener, but as my programs are demanding more I have gotten the recommendation to switch over to KeyBinds.
First of all I have tried to add keybindings to JFrame which didn't work ( I don't understand what JComponent I need to use. ). Therefore I tried moving the program over to a JPanel and then adding it to a JFrame, however the Key bind do not react when the desired button is pressed (in this case it's the "1" button);
In the method call I have set the action to be Print "Hi". Here is the code:
public class Panel extends javax.swing.JPanel {
JPanel Panel = new JPanel();
/**
* Creates new form Panel
*/
public Panel() {
addKeyBinding(Panel, KeyEvent.VK_1, "1Button", (evt)->{
System.out.println("Hi");
});
initComponents();
}
.....
And here is the method
.....
public static void addKeyBinding(JComponent comp, int keyCode, String id, ActionListener actionListener){
InputMap im = comp.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
ActionMap ap = comp.getActionMap();
im.put(KeyStroke.getKeyStroke(keyCode, 0, false),
id);
ap.put(id, new AbstractAction(){
#Override
public void actionPerformed(ActionEvent e) {
actionListener.actionPerformed(e);
}
});
}
What am I doing wrong? Thanks!
The key bindings are for your form panel, right? I think you're misunderstanding a few concepts about classes and objects. Also it's hard to help without seeing the full code. But your error is very likely caused by this line:
addKeyBinding(Panel, KeyEvent.VK_1, "1Button", ...
which should be:
addKeyBinding(this, KeyEvent.VK_1, "1Button", ...
The variable Panel should be replaced with the keyword this thus referencing the actual form panel.
It also should be created wherever you're creating your window so this line can also be removed:
JPanel Panel = new JPanel();
There are many things wrong with your code. I can't imagine the code in the first snippet even compiles. You are trying to name a variable the same as your classname.
Your class has no reason to extend JPanel since it isn't a new type of JPanel. Simply remove your extends. Then change the first line to:
JPanel panel = new JPanel();
Then pass lower-case panel to the addKeyBinding method.
If for some strange reason you want to keep your class extending JPanel then pass this as the first parameter to addKeyBinding as /u/tiiv said and remove the JPanel Panel = new JPanel line since that isn't needed (as you have it written now your class is the JPanel).
As far as which component to use JFrame is a top-level container so that is usually your main application window. And then you put JPanel and other components in the JFrame. There are actually 4 top-level containers in swing (JFrame, JWindow, JDialog, and JApplet) but JFrame is generally the one you will use as your main app window.
I hope that helps.
i recently code a system homepage that include the background image. After i set the background, the button that i created cannot show properly. It just appear after i use the mouse and point to the buttons' location. Can someone teach me how to fix this problem? Your help are appreciated. The codes are as below:
public class HomePage extends JFrame{
private JPanel button = new JPanel();
private JButton time = new JButton("Bus Schedule");
private JButton reserve = new JButton("Booking");
private JButton info = new JButton("About Us");
Container con = getContentPane();
public HomePage(){
setTitle("Bus Reservation System");
setSize(650,500);
setLocation(360,100);
setVisible(true);
setResizable(false);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setBackground();
setButton();
}
public void setBackground(){
JLabel background = new JLabel(new ImageIcon("C:/User/Desktop/Assignment/bg.jpg"));
con.add(background);
background.setLayout(new FlowLayout());
con.add(button);
}
public void setButton(){
Font but = new Font("Serif" , Font.ITALIC , 20);
info.setFont(but);
time.setFont(but);
reserve.setFont(but);
button.add(info);
button.add(time);
button.add(reserve);
con.add(button);
}
After you call setVisible(true), if you perform certain actions, you must manually validate() or revalidate() your window.
It is simpler to just call setVisible() after you have initialized all of the desired settings and membership of the window.
/* setVisible(true); -- wrong place */
setResizable(false);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setBackground();
setButton();
setVisible(true); // proper place
Simple mistake (probably a typo?), you are setting the layout of the JLabel, you intended to set the layout of the Container. Do con.setLayout(new FlowLayout()); instead of background.setLayout(...)
Also, I believe your path to the file is incorrect. For testing, just put the file in the project and do a path like "bg.jpg", if that works, we can verify this. For me that works. The reason I believe this is the issue is because you specify C:/Users, but then never give the folder for the specific User. A correct path would be C:/Users/Your_name/Desktop/Assignment/bg.jpg
I don't know for sure on that path part, since I'm not on your system. However, for me, if I run your code in my eclipse, this fixes it.
edit:
One last thing, the image isn't really going to be a "background" image with the current code because it will move the buttons underneath it instead of on top of it with the FlowLayout. You may want to use a different Layout.
First of all as already noted, all components should be added to the frame BEFORE invoking setVisible(true) on the JFrame.
JLabel background = new JLabel(new ImageIcon("C:/User/Desktop/Assignment/bg.jpg"));
con.add(background);
background.setLayout(new FlowLayout());
con.add(button);
Based on the above code you are adding two components to the content pane so the hierarchy of your GUI looks like this:
- frame
- content pane
- background
- button
It seems to me you want your GUI to look like this:
- frame
- content pane
- background
- button
So your code should be:
JLabel background = new JLabel(new ImageIcon("C:/User/Desktop/Assignment/bg.jpg"));
con.add(background);
background.setLayout(new FlowLayout());
//con.add(button);
background.add( button );
I am very confused. Why would this method not work for displaying an image:
private void showImage(final BufferedImage image){
SwingUtilities.invokeLater(
new Runnable(){
#Override
public void run(){
ImageIcon icon = new ImageIcon(image);
JLabel label = new JLabel();
label.setIcon(icon);
add(label, BorderLayout.CENTER);
}
}
);
}
My class extends JFrame, so that's why I'm not doing something like:
frame.add(label);
I am very confused. I have tried this without the whole SwingUtilities thing and also I have tried label.setVisible(true)
What the heck am I doing wrong here? When I run it I know this method is being called with a completely okay BufferedImage (I had it output something in the method). I expected a JLabel to come up with my image on it, but just the JFrame came up, no image in sight.
add(label, BorderLayout.CENTER);
When you add (or remove) a component from a visible GUI the basic code is:
panel.add(...);
panel.revalidate();
panel.repaint();
In your case you would revidate the frame since you are adding the label to the content pane of the frame.
That is you need to invoke the layout manager, otherwise the component has a size of (0, 0) so there is nothing to paint.
However, a better solution would probably be to add the label to the GUI when you create the frame.
Then to change the icon you just do:
label.setIcon(...);
No need to create a new JLabel every time you want to change the image.
Hello
I'm an amateur trying to learn/improve my understanding of Java by writing a score card for archery. I ‘m trying to produce a GUI and so far have successfully produced on a JPanel a row of 18 labels of differing sizes and colours suitable for scoring a dozen.
I then tried to add five of these 'labels panels' to another panel to build up a grid and save having to create and add as many as 150 labels in some cases . No success so far as the original labels panels will not show up. All the panels are displayed on a JFrame
I've tried a number of different ways of getting the code to work, using the Java tutorial and googling the internet and studying similar problems on this site but I'm going round in circles. I must have missed something somewhere and hope that you may be able to help.
I'm using Java 6 and JGrasp v1.8.8_01 as an IDE
The following code for the labels panel has been cut down as much of it is repetitive.
import javax.swing.*;
import java.awt.*;
public class ArrowScoreLabels extends JPanel{
public JPanel createContentPane(){
JPanel panelForLabels = new JPanel();
panelForLabels.setLayout(null);
//Code creates 18 labels, sets the size, position, background colours, border and
//font and adds the labels to the’panelForLabels
JLabel scorelabel1;
scorelabel1 = new JLabel("",JLabel.CENTER);
scorelabel1.setBorder(BorderFactory.createLineBorder(Color.black));
scorelabel1.setFont(new Font("Arial", Font.ITALIC, 26));
scorelabel1.setLocation(0, 0);//first value differs for each label
scorelabel1.setSize(35, 35);
scorelabel1.setOpaque(true);
panelForLabels.add(scorelabel1);
panelForLabels.setOpaque(true);
return panelForLabels;
}
}
Running the following class shows the 18 labels on panel
import javax.swing.*;
import java.awt.*;
public class TestArrowScoreLabels {
private static void createAndShowArrowLabels() {
//Create and set up the window.
JFrame frame = new JFrame("To score one dozen");
//Create and set up the content pane.
ArrowScoreLabels asl = new ArrowScoreLabels();
frame.setContentPane(asl.createContentPane());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(676, 73);
frame.setVisible(true);
}
//Main method to show the GUI/
public static void main(String[] args) {
SwingUtilities.invokeLater(
new Runnable() {
public void run() {
createAndShowArrowLabels();
}
});
}
}
The following code for the second panel is similar, compiles but only shows the second green JPanel and not the panel with the labels.
import javax.swing.*;
import java.awt.*;
public class FiveDozenScorePanel{
public JPanel createContentPane(){
//A bottom JPanel on which to place five dozenpanels.
JPanel fivedozenpanel = new JPanel();
fivedozenpanel.setLayout(null); //requires absolute spacing
fivedozenpanel.setSize(676,185);
fivedozenpanel.setBackground(Color.green);
//Label panels for five dozen
ArrowScoreLabels dozenscorepanel1, dozenscorepanel2,
dozenscorepanel3,dozenscorepanel4,dozenscorepanel5;
//Create the 5 dozenscorelabels.
dozenscorepanel1 = new ArrowScoreLabels();
dozenscorepanel1.setLocation(5,5);//y value changes for each panel
fivedozenpanel.add(dozenscorepanel1);//plus the other 4
fivedozenpanel.setOpaque(true);
return fivedozenpanel;
}
private static void createAndShowDozenPanels() {
JFrame frame = new JFrame("To score five dozen");
FiveDozenScorePanel fdsp = new FiveDozenScorePanel();
frame.setContentPane(fdsp.createContentPane());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Display the window
frame.setSize(700, 233);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(
new Runnable() {
public void run() {
createAndShowDozenPanels();
}
});
}
}
I've also tried frame.getContentPane().add(fdsp); - frame.pack(); and read so much about paint methods that I'm totally confused.
I can get the ArrowScoreLabels image to appear directly onto a JFrame rather than a JPanel but only one of them and not five.
I would appreciate being pointed in the right direction. Thankyou for your time.
Update - 14th Dec 2010
I have managed to display the panelForLabels Jpanel on another Jpanel on a JFrame. This was done by adding the following code to the class ArrowScoreLabels. The original createContentPane() method was renamed createRowOne(). The panelForLabels was coloured red and the fivedozen panel yellow to ascertain which was showing. However I was only able to persuade the programme to display one row of labels despite a great deal of experimentation and research.
public static JPanel createContentPane(){
//Bottom panelto hold rows of labels
JPanel fivedozenscorepanel = new JPanel();
fivedozenscorepanel.setLayout(null);//requires absolute spacing
fivedozenscorepanel.setSize(660,180);
fivedozenscorepanel.setBackground(Color.yellow);
fivedozenscorepanel.add(createRowOne());
fivedozenscorepanel.setOpaque(true);
return fivedozenscorepanel;
}
The only way I displayed the 5 rows of 18 labels was to create all 90 in the ArrowScoreLabels class and then add them to one JPanel using absolute spacing and then to a JFrame.
I've taken note of pstantons advice - thankyou for that - and I'm looking into using the MigLayout Manager.
simple answer: use a layout manager. don't use absolute positioning.
just comment out all of your calls to setLocation and setLayout and swing will use the default FlowLayout.
for more control over the display, use a different layout manager.
also, if you use multiple panels you will have trouble aligning things in different panels unless they contain the same number of components which are exactly the same size so consider using one panel for all of the labels.
you can achieve just about any layout you need using MigLayout.
EDIT: in your example, there's no need for ArrowScoreLabels need to extend JPanel since you are doing the work in createContentPane to construct a separate JPanel. later in your code you call new ArrowScoreLabels() wich will just return a blank JPanel, instead you need to call new ArrowScoreLabels().createContentPane()
if you want ArrowScoreLabels to extend JPanel, implement public ArrowScoreLabels() ie the constructor instead of createContentPane.
I've the impression you don't set a size to your dozenscorepanel1. So, set a size :-)
Be careful with the layout null, because it's a pain ; you always forget something. Write your own, or use an existing one.