Why JFrame colour is changing by changing content pane colour? - java

If the frame is placing on top of the content pane the exterior colour to the user is colour of JFrame. Here even i'm painting the frame after content pane but content pane colour will be displayed. Why?
public class GUI {
public static void main(String[] args){
JFrame frame = new JFrame();
frame.setSize(300,300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
Color myColor = new Color(100,100,100);
frame.setLocationRelativeTo(null);
frame.getContentPane().setBackground(myColor);
frame.setBackground(Color.red);
}
}

You shouldn't be setting the background of the JFrame itself. You CAN, yes, but it doesn't work very well.
It's got a content pane that covers the whole frame, so any color "underneath" will be covered up, as you've found.
All layout and styling should happen in the content pane.
You can set the content pane to a container of your choice, though, with a special layout or whatnot.
Also, when you say "painting the frame after the content pane" that's not actually happening. :) You're setting the background color after you set the background of the content pane, but it doesn't actually get repainted until its repaint flag is triggered by the application runtime.
Then it goes and checks what color is set, and paints. The order that you call the setters doesn't really matter.

Related

Removing JFrame Border?

I have a Java Swing GUI and everything in my JFrame is offset by a few pixels. On MacOS, I had to offset everything by 12 pixels downward to account for it. On Windows, everything is shifted to the left and downward as well. I discovered that
setUndecorated(true);
removes the JFrame border (which I suspect is the cause of my problems) but it also removes the title bar.
Is there a way I can remove the JFrame border (or some other alternative to make sure everything is centered) and still keep the title bar? I need the title bar so that I can move the JFrame around and have the maximize/minimize/close functions.
Also, the layout is set to null in case that matters. (Everything I'm doing is pixel - based so I cannot set it to anything else).
Thanks.
I found a solution after Googling a bit more. Calling
getContentPane().setPreferredSize(...)
pack();
inside the JFrame constructor will adjust everything so that the titlebar and borders will not impact the view of the content pane.
For anyone else that may need this, you have to set the preferred size of the content pane specifically as that is what you want to appear correctly.
This way you can keep the titlebar and all the normal functionality of a JFrame window that you would otherwise lose with setUndecorated(true);.
The reason why you are adding 12px is because this is consume by the Title and border.
If you use setUndecorated(true) You will loose the title bar and you have to implement the addWindowListener to add a location changing of of an application.
The best way to do is:
Class Main{
public static void main(String[] args){
//JFrame
JFrame frame = new JFrame();
//Create a Main Panel and setPreferred Size and not set Size or set Bound
JPanel mainPanel = new JPanel(); //You value down
mainPanel.setPrefferedSize(new Dimension(x, y));
frame.add(mainPanel);
//and then in last add
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//the pack method help you to setSize of the JFrame According to the
//Component size
frame.pack();
frame.setVisible(true);
}
}

Java JPanel and JFrame border dragging

I am opening a window with the following:
JFrame clientFrame = new JFrame("Frame");
clientFrame.setLayout(new BorderLayout());
final JPanel client_panel = new JPanel();
client_panel.setLayout(new BorderLayout());
client_panel.add(new Applet());
client_panel.setPreferredSize(new Dimension(765, 555));
clientFrame.getContentPane().add(client_panel, "Center");
clientFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
clientFrame.pack();
clientFrame.setVisible(true);
the frame has a random picture on it.
By default when you drag the bottom border upwards, it will naturally remove from the image from the bottom of the image.
The same if you drag the top border downwards it will again remove incrementally from the bottom of the picture.
How do I swap it around so instead it removes form the top of the picture instead of from the bottom?
clientFrame.getContentPane().add(client_panel, "Center");
Don't use magic values. People don't know where "Center" comes form. Use variables provided by the API:
clientFrame.getContentPane().add(client_panel, BorderLayout.CENTER);
What you are asking is not possible with any layout manager that I am aware of. The problem is that the layout manager only knows about size available to the component. It does not know why the size changed (ie, drag up or down). So the layout manager can only define rules based on the space available.
As a simple test use a JPanel with a BorderLayout. Then create a JLabel with containing an ImageIcon. Add the label to this panel and then add the panel to the content pane of the frame.
If you add the label to the BorderLayout.CENTER, then the image is centered in the space available so you lose part of the top and bottom.
If you add the label to the BorderLayout.PAGE_START then space is always taken from (or given to) the bottom of the component.
If you add the label to the BorderLayout.PAGE_END then space is always taken from (or given to) the top of the component.
If you want to consider the drag up or down of the frame then the solution gets much more complicated because you will need to add a ComponentListener to the frame and handle the componentResized and componentMoved methods. You will then need to track the previous state of the frame and then determine which properties have changed and then you will need to do custom painting of the image based on the property changes or you will need to write a custom layout manager that is aware of the property changes.

Display a JPanel on full screen

Hello I have a JPanel who contained a JTable and a TextField. I want that the display screen is displayed in full screen because in my case it appears half of the screen.here's not a parameter of screen size that I have to specify or change?
This is the result:
public MainWindow()
{
super("Fullscreen");
getContentPane().setPreferredSize(
Toolkit.getDefaultToolkit().getScreenSize());
pack();
setResizable(false);
show();
getContentPane().setPreferredSize(Toolkit.getDefaultToolkit().getScreenSize());
pack();
setResizable(false);
show();
A few problems with the code:
You can't just set the size of the content pane to be the size of the screen. A frame has decorations (title bar, borders) that need to be considered.
The order of pack() and setResizable(...) is wrong. The pack() statement needs to be invoked AFTER you add components to the screen and after you set the resizable property of the frame.
The show() method is not used anymore.
If you just want to display the frame maximized the code is:
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
frame.setResizable(false);
frame.pack();
frame.setVisible(true);
I suggest you look at the FrameDemo found in the Swing tutorial on How to Make Frames for working code to get you started. I don't know where you found your current code example but I would lose the code and learn how to do Swing coding properly. Bookmark the Swing tutorial for examples of all Swing basics.
the frame has a setSize method, where you can pass the dimension you want.
to get the screen size you can use
Toolkit.getDefaultToolkit().getScreenSize()
setExtendedState(JFrame.MAXIMIZED_BOTH);
Add a ComponentListener with componentResized() method. When the size changed make equal your JPanel's and JTable's size to JFrame's size. And also, while defining JPanel and JTable make their sizes' equal to JFrame's size.

Making a glassPane fit with the dimensions of a JPanel

StackOverflow!
I'm working on a project, in regards to making a navigation system, and we're in the beginning stages, working with drawing the map and navigating it itself.
We have a function, where you should be able to draw a square on top of the current data having been drawn already. I want to avoid having to repaint all of the data for the roads all over again, with each mouseDragged action event. To do this, I found that using a glass pane would be the optimal choice.
The problem recides with the dimensions of the glasspane and the coordinates it reads. When I click on a certain spot on our JPanel (which we use to draw on), it knows how and where to zoom in properly, but when I draw my square, it is being drawn a specific amount of pixels above my mouse's position. This seems to be due to the fact that my glass pane dimension does not correspond to my JPanel dimensions. The glass pane seems to also cover my menubar, whereas the JPanel itself does not read clicks which occur on the menubar.
I want to somehow fit a glasspane to my JPanel, and I've tried a few different things.
One thing I tried, was to draw on a JRootPane instead of a JPanel, but that doesn't seem to be possible. Then I tried to just retrieve the "MyGlassPane" class from my JPanel (which also has its own class), and call it's repaint method, but that's where the issue originated from.
Most lately, I've retrieved the JRootPane which the JPanel itself uses or is part of, and then retrieved the glasspane of this JRootPane, but it seems that my menubar, added to the JFrame, is also part of this JRootPane, meaning that the glasspane covers the menubar as well.
Here is some very simplified code, which covers the issue, but not the mouse-listening nor data-drawing aspects. It does however show off the fact that it's annoying that the rectangle is being drawn on top of the menubar.
import java.awt.*;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.*;
public class TestForRootPaneStuff {
JFrame frame = new JFrame();
JRootPane root;
JPanel panel = new JPanel();
JLabel label = new JLabel("Hello there!");
public void rootPanePls()
{
frame.add(panel);
panel.add(label);
root = panel.getRootPane();
JMenuBar menubar = new JMenuBar();
JMenu prettyMenu = new JMenu("Pretty");
menubar.add(prettyMenu);
frame.setJMenuBar(menubar);
MyGlassPane gp = new MyGlassPane();
root.setGlassPane(gp);
gp.setVisible(true);
gp.setEnabled(true);
gp.repaint();
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setPreferredSize(new Dimension(250, 250));
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
TestForRootPaneStuff derp = new TestForRootPaneStuff();
derp.rootPanePls();
}
private class MyGlassPane extends JComponent implements ItemListener
{
//React to change button clicks.
#Override
public void itemStateChanged(ItemEvent e) {
setVisible(e.getStateChange() == ItemEvent.SELECTED);
}
//Draw the square for zoomToSquare
#Override
protected void paintComponent(Graphics g) {
g.setColor(Color.BLUE);
g.drawRect(10, 10, 100, 100);
}
}
}
And this is a corresponding screenshot, as a result of running this code. (I can't post direct images, due to lack of activity on here)
I hope my explaination makes at least a bit of sense. I'm aware that my explaination is perhaps a bit too in-depth as for actually resolving the issue, but I felt like it was necessary to invelop you guys a little bit more into my situation, and my reason for needing a solution for this.
TL;DR:
I need a way to make a glassPane (retrieved/set from somewhere) completely fit the dimensions of a specific JPanel, so that I can receive the same mouse event coordinates for both the JPanel and the glasspane. See code above for visualization of the issue.
Is there a smart way to go about this? Setting the RootPane glasspane was my final idea...
Thanks in advance, if anyone has any insight to bring!
Kirluu~
not an asnwer longer comment, just guessing based on wrong/uncomplete code posted here
use JLabel instead of JComponent, JComponent hasn't any LayoutManager in API, sure JLabel too, but it to be container very simple like as contianer, is transparent, anything in paintComponent can be (semi) transparent
your code is incompleted why is there ItemListener, don't put JComponents to JComponent as contianer, use JPanel instead, or mentioned opaque JLabel is easiests of ways for GlassPane, 1st code line should be super.paintComponent in paintComponent, dispose() all custom painting for anything placed/laid in GlassPane
JLabel can has easilly to copy the coordinates from JPanel, use ComponentListener added to JPanel, with delaing (350-600) events from ComponentListener (one event per one pixel) by using Swing Timer, EDIT if resize continue call timer.restart() </EDIT, if resize ended then Swing Action/ActionListener will fire setBounds for JLabel (whatever) placed in GlassPane
search for simple RepaintManager (just by covering JLabels bounds in GlassPane) for animation in GlassPane

How to put a text area (JTextArea) into a window (JFrame)?

I have a working code which creates a window with a text area. The code is here. I try to figure out how this code works. A lot of things are clear:
The main-method creates an instance of the TextAreaDeom class (which is subclass of the JFrame). In other words, the main-method creates a window.
In the main-method we set some "parameters" of the window and make it visible.
It is not clear to me, in which place we put the text area in the window. I see that the text area is created right before the constructor. I also see that in the constructor we set some "parameters" of the text area (setText). I also see that in the constructor we create a a scrolling area and set some parameters for it. I see that the scrolling area is "connected" to the text area (since we use the instance of the text area to create the scrolling area). I also see that we create an object called "content" (using the current window) and we "add" the scrolling area to the "content".
But at which place the text area is added to the window? May be I can say that the text area is added to the scrolling area and the scrolling area is added to the "content" and the content is a part of the window-object?
in line 16 you create a JScrollPane which wraps around your JTextArea object. On line 21 you add this JScrollPane, which contains your TextArea to the ContentPane of the JFrame.As you call getContentPane() instead of creating a new one the ContentPane is already part of the JFrame.
All elements of the ContentPane will be displayed as part of the JFrame. The add method of JFrame is only for convenience and forwards the call to the JFrames ContentPane.
The scroll pane scrollingArea is created with the text area inside. scrollPane, was constructed with text area m_resultArea (see the documentation for JScrollPane's constructor). is then added to the frame's content pane.
The GUI elements should be constructed on the EDT. Here is a more reliable main() method for the program cited above.
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame win = new TextAreaDemo();
win.setTitle("TextAreaDemo");
win.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
win.pack();
win.setVisible(true);
}
});
}

Categories