I'm new to Java Swing (and fairly new to Java in general) and I've been messing around with Swing for a while, but after making some changes my panels stopped displaying and I don't know why.
When using isDisplayable() on my JPanel object it returns false. After more investigation my program does not seem to display graphics at all.
Even a simple piece of code doesn't work for me anymore:
public class window extends JFrame {
window(){
setBounds(100,100,1200,700);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBackground(Color.black);
setVisible(true);
}
public static void main(String[] args) throws IOException{
new window();
}
I have no idea what I changed for this to happen, but all I get is a blank a completely blank window.
Any help is appreciated a lot!
See the code comments.
import java.awt.Color;
import javax.swing.*;
public class BlackWindow extends JFrame {
BlackWindow(){
setBounds(100,100,400,100);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// sets the frame black, not the content pane
//setBackground(Color.BLACK);
getContentPane().setBackground(Color.BLACK);
setVisible(true);
}
public static void main(String[] args) {
new BlackWindow();
}
}
This example also speaks to a few general principles we follow when using Swing's JFrame:
Don't extend the JFrame class, just use an instance of one.
Don't do anything significant to the coloring or styling of a frame, instead color (for example) a JPanel and add it to the frame.
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 am writing this code so that it will add JPanels and will change the background color when clicked. The code in the class that runs the JFrame class is:
import javax.swing.*;
public class project9Driver {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
Project9 w=new Project9();
w.setVisible(true);
w.setSize(900, 900);
}
}
The Project9 class is:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Random;
public class Project9 extends JFrame implements MouseListener{
JPanel panes[]=new JPanel[64];
public void Project9(){
JFrame mainFrame=new JFrame();
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container mainBox=mainFrame.getContentPane();
mainBox.setLayout(new GridLayout(8,8));
mainBox.addMouseListener(this);
for(int i=0;i<=63;i++){
panes[i].setBackground(Color.WHITE);
mainBox.add(panes[i]);
}
}
public void paint(Graphics g){
super.paintComponents(g);
}
public void mouseClicked(MouseEvent e) {
for(int i=0;i<=64;i++){
if(e.getSource()==panes[i]){
Random xR=new Random();
Random yR=new Random();
Random zR=new Random();
int x=xR.nextInt(255),y=yR.nextInt(255),z=zR.nextInt(255);
panes[i].setBackground(new Color(x,y,z));
}
}
}
}
Whenever I try to run the program, it comes up with an empty GUI window. What am I missing?
Project9 is a Frame, and you're creating another Frame inside of Project9 and you're not showing it, and becouse of that, just Project9 (w) is draw on screen, but it doesn't have anything.
You have to use "this" instead of another frame.
public class Project9 extends JFrame implements MouseListener{
JPanel panes[]=new JPanel[64];
public void Project9(){
//JFrame mainFrame=new JFrame(); delete this.
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container mainBox= this.getContentPane();
Three answer all point out different problems with your code.
You should start with a proper working example. The TopLevelDemo.java code from the Swing tutorial on Using Top Level Containers will show you the basics and the proper way to create GUI components.
You should not even be extending JFrame. It is important that all components are created on the Event Dispatch Thread which is why the invokeLater() code is used in the tutorial.
Use the tutorial for examples of using all Swing components. Other example will show you how to extend JPanel for a more complex GUI. You don't need to extend JFrame.
The original problem I noticed with the code is:
public void paint(Graphics g){
super.paintComponents(g);
}
Don't override the paint() method. There is no reason to do this!
The paint() method is for painting and you are not doing any custom painting.
First problem is this that you are using constructor Project9 w=new Project9();
and in class Project9 you are defining method public void Project9(){ you should remove void keyword.
public Project9(){
//JFrame mainFrame=new JFrame(); delete this.
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container mainBox= this.getContentPane();
The documentation for Processing PApplet states
there's nothing to prevent you from embedding a PApplet into a JFrame ... If people want to use Swing, they can embed themselves as they wish.
However, I did not find any example how to do this, and when I have tried it, the result never worked well - with the code I have now my PApplet is embedded, I can even create a menu bar, but the applet does not react to resizing the JFrame. Also, the frame member of PApplet is null, therefore any articles I have found (like this one on Processing forum or Window Size and Full Screen in the Processing docs) regarding this do not work for me.
Here is what I have now, more or less copied from Using a Processing Sketch as a Java Component:
import processing.core.PApplet;
public class CurveEditorApplet extends PApplet {
public static void main(String args[]) {
new CurveFrame();
}
}
and
import javax.swing.*;
public class CurveFrame extends JFrame {
CurveFrame() {
setSize(600, 600);
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
panel.setBounds(20, 20, 600, 600);
Curve2D sketch = new Curve2D();
panel.add(sketch);
add(panel);
sketch.init();
sketch.frame = this;
setVisible(true);
setResizable(true);
}
}
How can I change it so that the applet is resized when resizing the main window?
I'm using the Intelij idea platform.
I have the following code:
package GUI.test;
import javax.swing.*;
public class Frame extends JFrame{
Frame(){}
public void main (String[] args){
new Frame();
}
}
I expected to see a JFrame after compiling this code, but was nothing appeared. What kind of problem can it be?
Frames are not visible by default--use the
setVisible(true);
method in order to display frames.
You also might want to take a look at other options such as
setSize(int width, int height);
method to resize a frame,
setLocation(int xLoc, int yLoc);
to move the frame, and
setTitle(String title);
to set the title of the component.
Aside, it is good practice to use a variable to hold components so they can be manipulated when needed.
You might want to add this
Frame()
{
setVisible(true);
setSize(100,100);
}
package GUI.test;
import javax.swing.*;
public class Frame extends JFrame{
private myFrame;
public Frame()
{
myFrame = new JFrame("put a title here"); //title not necessary but it's there if you want it
myFrame.setSize(400,400); // sets the window size
myFrame.setVisible(true); // toggles the frame to be visible inside the window
myFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); // this will terminate the VM once the *last* JFrame is closed, so you can have multiple frames open and just close one
}
public void main (String[] args){
new Frame();
}
}
Thanks a lot for answering. I wrote an example without details. I have added: setVisible(true);
setSize(100,100);
to a class constructor. But i havent seen form jet.
Have to say about one feature. I'm not running method main in class Frame, i'm compiling this class Frame. In my previous exersises with java i allways run main method, but when i tried to work with GUI form and used swing library, ability to run method main have dissapiared.
If you haven't cought what i mean, i'd send a screenshot.
I've looked at several other posts, and I have yet to find a clear answer. I don't entirely understand the paint method, which is probably my problem, but nowhere can I find a clear explanation. Can someone help me get this one working? The issue is that the paint method is not running. Everything else seems to work fine, but I do not see the oval I tell the program to render in the frame.
import java.awt.Color;
import java.awt.Component;
import java.awt.Frame;
import java.awt.Graphics;
#SuppressWarnings("serial")
public class TestObject extends Component {
MouseResponder mouseListener = new MouseResponder(); // Creates a new mouse listener.
WindowResponder windowListener = new WindowResponder(); // Creates a new window listener.
Frame mainFrame = new Frame(); // Makes a new frame.
public TestObject() {
mainFrame.setSize(400,500); // Makes the new frame 400 by 500 in size.
mainFrame.setLocationRelativeTo(null); // Sets the location of the window to center it.
mainFrame.setTitle("A Test program!"); // Sets frame label.
mainFrame.setBackground(new Color(199,199,199)); // Sets the background color of the window.
mainFrame.addWindowListener(windowListener); // Adds the window listener so close works.
mainFrame.addMouseListener(mouseListener); // Adds the mouse listener to the frame.
mainFrame.setVisible(true); // Makes the new frame visible.
System.out.println("[TestObject] Window" + // Prints a console message when main window is launched.
" configured and launched.");
}
public void paint(Graphics pane) {
System.out.println("[TestObject] Painting.");
pane.setColor(Color.BLACK);
pane.drawOval(10,10,10,10);
}
}
Other Info:
MouseResponder and WindowResponder are separate functioning classes.
The TestObject class seen above is called by a main class which
creates a new TestObject. The frame displays successfully as I
specify.
Thank you for any help!
-Docithe
You are late for your homework buddy !
Take a new java file.
Create a class
Make it extend JFrame
override the paint method
put a println in it
Take a second file
put a main in it
instanciate your first class and call show
move the window around, println should print out, meaning your code in paint is executing.
That's the way to do it in OOP, and for sure in java. Read more.
paint() is responsible for rendering a component when it is visible.
At least in your code snippet, you did not add the test-component to the frame - thus, it is not displayed and not painted.
public TestObject() {
//...
mainFrame.add( this );
//...
}
This still might not work because your Test Component is 0x0 pixel.
So you also
#Override
getPreferredSize(){
return new Dimension( 20, 20 );
}
you are mixing two things here, creating a frame and creating a component. If I understand you correctly, you want to create a frame and within that frame have a custom component draw an oval.
The component is just this:
public class TestObject extends Component {
public void paint(Graphics pane) {
System.out.println("[TestObject] Painting.");
pane.setColor(Color.BLACK);
pane.drawOval(10,10,10,10);
}
}
and your main program looks more like this:
public static void main(String[] args)
{
MouseResponder mouseListener = new MouseResponder();
WindowResponder windowListener = new WindowResponder();
Frame mainFrame = new Frame();
mainFrame.setSize(400,500);
mainFrame.setLocationRelativeTo(null);
mainFrame.setTitle("A Test program!");
mainFrame.setBackground(new Color(199,199,199));
mainFrame.addWindowListener(windowListener);
mainFrame.addMouseListener(mouseListener);
mainFrame.add(new TestObject());
mainFrame.setVisible(true);
}
I am not saying this code will run, but it splits the two things in what they should be, a main program creating the frame, and a component painting an oval. I agree with Snicolas on the reading more...