intellij and swing - changing jpanel size - java

I am using intellij with swing.
My application runs on different computers with different monitors.
I want to display my form in different sizes.
I have a JPanel (not the main . inner jpanel ) set to (-1,670) in the intellij gui editor.
And I try to change it with this code :
MyFormUI myform = new MyFormUI();
if (thisIsTheCase){
myform.setLongView()
}
and in MyFormUI ->
public void setLongView(){
myPanel.setPrefferedSize(new Dimension(-1, 1000))
myPanel.repaint() ;
revalidate();
// I tried also repaint and revalidate on a higher jpanel in the hierarchy
}
When I change it in the gui editor - it does change, but not through code.
any suggestions?

myPanel.setPrefferedSize(new Dimension(-1, 1000))
myPanel.repaint();
revalidate();
Not sure what the -1 does.
The code should be:
myPanel.revalidate();
myPanel.repaint();
The revalidate() actually redoes the layout of the component and the repaint just paints it. In your code you are repainting before redoing the layout.

Preferred size is, as you may guess, only preferred. If the underlying layout manager does not want to use this setting, it is free to discard it. IntelliJ IDEA is using its own layout manager, so you need to check if the panels Horizontal and Vertical size policies allow resizing.
It will be easier to diagnose the problem if you describe your layout in more details.

Related

Java Positioning Problem of JLabel in JFrame

I´m creating a TileMap out of JLabels and my Problem is that the last Tile is not placed right.
For some reason the last JLablel is on a wrong position. I think this Image:
and the Code explains what my problem is.
Btw. I am using BlueJ (maybe there is a bug in it, that I dont know)
Thanks for help!!!
//create Frame
this.setSize((size+2)*imageSize+16,(size+2)*imageSize+39);
this.addKeyListener(this);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.getContentPane().setBackground(Color.black);
this.setVisible(true);
//create MapJLabels
for(int x = 0;x<size;x++){
for(int y = 0;y<size;y++){
mapJLabels[x][y] = new JLabel();
this.add(mapJLabels[x][y]);
mapJLabels[x][y].setSize(imageSize,imageSize);
mapJLabels[x][y].setLocation((x+1)*imageSize,(y+1)*imageSize);
mapJLabels[x][y].setVisible(true);
}
}
The code is attempting to set the size/location of the component. This implies you are using a null layout. Don't. Swing was designed to be used with layout managers. You should use the GridLayout. Read the section from the Swing tutorial on Layout Managers for more information.
You create an empty JLabel. By default a JLabel is transparent. I'm not sure now the picture you posted is created from the code you posted. I don't see how the grid is populated with images etc.
Swing components are visible by default so there is no need for the setVisible(true)
Your code attempts to set the size of the frame. Again, don't. When using layout managers you just pack() the frame and the size will be calculated automatically.
Your code attempts to leave space between the frame and labels. Don't. If you want extra space you can add an EmptyBorder to the panel. Read the section from the Swing tutorial on How to Use Borders
You code is using a KeyListener. Don't. Swing was designed to be used with Key Bindings
Components should be added to the frame BEFORE the frame is made visible.
The posted code looks reasonable, but since we can't see where you change the background of the labels or where you add icons to the labels, we don't know what the rest of your logic is doing. The problem could be there.
If you need more help after fixing the above problems then post a proper minimal, reproducible example that demonstrates your new problem.

How to force-refresh/repaint a JScrollPane?

I am adding lots of components (JPanels, JLabels etc.) into a JScrollPane programagically at the start of my program based on some stuff from a database.
It seems that this procedure is too fast for the GUI(?), so the JScrollPane does not always update correctly, i.e the scroll bars are not visible even though the inner JPanel is bigger than the visible area.
Resizing the Window (JFrame) fixes the problem, as I assume Java is re-printing the components when they are resized.
As a test, I have added a debug-button that I can click after the startup of the program has finished. I am trying to force the JScrollPane to "refresh" itself.
I have tried doing:
scrollpane.repaint();
scrollpane.validate();
scrollpane.revalidate();
None of them seems to work. However, if I change the border (or any other layout related to the JScrollPane), it refreshes correctly.
scrollpane.setBorder(new LineBorder(Color.RED));
So I basically have 2 questions.
What is the command for forcing the scrollpane to "refresh"? Obviously it is doing some kind of "repaint" thing when I am adding the border. How can I run that only?
Is there a way of "pausing" the printing of components as they are added and resume it again after I added all the wanted components? As it is now, I basically "see" the components being added on the screen (even though it is really fast). It would be better if I can add all the components I want and THEN tell the program to print it to the screen/JFrame.
The basic code for adding components to a visible panel is:
panel.add(...);
panel.add(...);
panel.revalidate();
panel.repaint();
Adding a component does nothing because the component still has a zero size so there is nothing to paint. When you invoke the revalidate() method the layout manager gets invoked so components will now have a location/size. The repaint() will then paint the components. The revalidate() will also cause the scrollbars to show when required. This of course assumes you are using layout managers.
The components are added to the panel so you invoke the methods on the panel, not the scrollpane.
In my case only
frame.pack();
helped to get the scrollbars on the JScrollPane, when the enclosed JPanel was resized dynamically.

Resize JFrame and Components Based On Computer Resoultion

I've made a java application in netbeans and am wondering how to have the size of the jframe half the width and height of the computer resolution and also having the components comply with this change. I tried putting code and it did make the frame half the height of the computer resolution but my components, such as buttons and textfields, stopped showing. How can I achieve this? Thanks.
(EDITED)
Set the JFrame's layout manager to GridLayout. In the properties window of the GridLayout itself (select in the navigator window) set columns to 1 and rows to 2. This should give you what you want and you won't have to get into the code.
This is the key code being called within the initComponents() method of your JFrame subclass (created by NetBeans) but it is important to understand where it is:
getContentPane().setLayout(new java.awt.GridLayout(2, 1));
I love Netbeans but you do have to understand the basics.
Good luck with your project. Swing is an awesome toolset that was way ahead of it's time.
As usual in this situation the key is using the right combination of layout managers for your containers. You're probably using NetBeans generated code (something I recommend you avoid until you are very comfortable with Swing coding), and it's probably having you use GroupLayout, a fine layout, but one that might not behave as well as you'd like on resizing components. I suggest that you go through the layout manager tutorial and try to nest JPanel containers and play with different layouts that re-size well such as GridLayout, GridBagLayout and BorderLayout to try to create the best layout that can re-size well.

java validate() method doesnt work properly

I have a JFrame inside of which is a jpanel that im using as the content pane.
So basically im using the jpanel to load content into on click. New content is returned as a Jpanel also so its ends up being jpanel -> inside jpanel -> inside Jframe. When i need to load in new content i clear the panel, load the new content and validate() the jframe & jpanel and the new content displays.
My problem is that when the new content displays its clear that the validate method is working because i can see the new interface but i can also see the old interface as if its become the background; i can resize the window and it just disappears and looks as it should.
Is this just the way validate works or can i fix it?
Edit: this worked. The problem was i wasn't calling repaint manually.
public BaseWindow setContent(JComponent comp){
contentPane.add(comp);
contentPane.revalidate();
contentPane.repaint();
return this;
}
Generally the code for adding/removing one or two components from a panel is:
panel.remove(..);
panel.add(...);
panel.revalidate();
panel.repaint(); // sometimes needed
However, if you are replacing all the components on the panel, then the better approach is to use a Card Layout.
You have already stated the revaliate() followed by repaint() doesn't work so the only suggestion I have is to post your SSCCE that demonstrates the problem.
Don't use validate. Use revalidate() instead.
Revalidate first calls invalidate() followed by a validate().
In Swing, you would rarely use validate().
Note: I also feel that maybe the old panel is not cleared/removed.Check again!
Validate() is for causing components to re arrange themselves according to the layoutmanager that you have installed. This is not really what you should be using.
I can't see your code, so I'm not sure exactly what you are doing. I could speculate that calling repaint() on your "inner panel" will solve the problem you are having...but really, if you are doing things properly, you shouldn't need to call repaint() or validate().
Make two JPanels, one with content A (e.g. your buttons), and one with content B (e.g. your "static" field). Use the "add()" and "remove()" methods on the parent container (the JFrame's content pane?) to swap these two JPanels with each other whenever you want to switch the content that is displayed in that part of the JFrame.
Then you shouldn't need to do anything else; it should just work.
I don't know if validate() makes any promise about fully repainting the container. You might have to call repaint() yourself to make it behave as you want to.
Here's another possible solution:
Put both JPanels in at the same time, side by side, and then make sure only one of them is ever visible at any one time:
JPanel p = new JPanel(new BorderLayout());
p.add( panelA, BorderLayout.EAST );
p.add( panelB, BroderLayout.WEST );
panelA.setVisible(true);
panelB.setVisible(false);
Then when the user clicks the button to switch panels:
panelA.setVisible(false);
panelB.setVisible(true);
The setVisible() method and BorderLayout should take care of validating, layout, and calls to repaint() for you.
I ended up fixing my issue (display not shown, buttons would stay clicked/weren't unclicking) by changing which panels were added/removed.
Problem:
frame.removeAll();
frame.add(getNewPanelDisplay());
frame.revalidate();
frame.repaint();
Solution:
//initializer()
mainPanel = new JPanel();
frame.add(mainPanel());
// ...
//update()
mainPanel.remove(0);
mainPanel.add(getTablePanel(), 0);
frame.revalidate();
frame.repaint();

Java: remove margin / padding on a JTabbedPane

I'd like to know how to remove the margins between my JtabbedPane and my JFrame content pane and between my JTabbedPane and its internal JPanel.
I circled the margins I want to remove.
the green line is here to show the gap between the jpanel inside the jtabbedpane.
I tried to look at some method named setMargin but it doesn't exist on a JTabbedPane. I also checked the Hgap and Vgap (both = 0) on the different layout (root content pane, my jpanel, etc).
So any suggestions are welcome.
Thanks.
.
I can't post images yet.
It is up to the look and feel to decide how much space is around components inside a tabbed pane - generally it will do this based on whatever is the default for your desktop. JTabbedPane does not have methods for setting the insets around internal components.
You can set this globally for all tabbed panes (caveat: Works on MetalLookAndFeel, will probably work for Windows L&F as well, probably won't work for GTK or Nimbus look and feel which are not based on BasicLookAndFeel). This will change the appearance of all tabbed panes in the VM:
UIManager.getDefaults().put("TabbedPane.contentBorderInsets", new Insets(0,0,0,0));
UIManager.getDefaults().put("TabbedPane.tabsOverlapBorder", true);
You probably also want to make sure your JTabbedPane has an EmptyBorder(0,0,0,0) and so do the components you put in it.
If this doesn't work on your target desktop, the alternatives are
if you don't care about your tabbed panes looking different from native application tabbed panes, the (unpleasant) alternative is to write your own TabbedPaneUI
set the UI delegate for the single JTabbedPane you want to look like this to MetalTabbedPaneUI or some other UI delegate that does respond to these properties
I just struck the same problem, and nothing anyone else said seemed to be a complete solution, so I came up with this:
import javax.swing.plaf.basic.BasicTabbedPaneUI;
tabbedPane.setUI(new BasicTabbedPaneUI() {
private final Insets borderInsets = new Insets(0, 0, 0, 0);
#Override
protected void paintContentBorder(Graphics g, int tabPlacement, int selectedIndex) {
}
#Override
protected Insets getContentBorderInsets(int tabPlacement) {
return borderInsets;
}
});
It works the same without overriding the paintContentBorder method, however doing so probably makes the UI slightly more efficient during resizes or similar, as the standard one seems to delegate out to a number of other methods.
Tested on Oracle Java 6 u43 for Linux in WindowMaker, Mac OS X 10.6.7 with Mac Java 6 u37 and Windows 7 with Java 7 u07, hopefully this helps someone :-)
Margins are added by setting borders on UI elements. Have a look at the settings of the border of your JTabbedPane.

Categories