Java JPanel.setOpaque(false) doesn't make JPanel Transparent - java

I am trying to make a gui where I use a splitPane with stuff on the left and the main content on the right. I realized that when the splitPane gets resized the content from the right panel moves accordingly to fit the new size which is not the behavior I am looking for, I want the main content on the right to remain as is when I resize. So I used a layeredPane to add the main content behind a split pane that has stuff on the left and a transparent panel on the right to show the main content behind it.
Here is a snippet of my code
JPanel phantomPanel = new JPanel();
phantomPanel.setOpaque(false);
JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, leftPanel, phantomPanel);
JLayeredPane layeredPane = new JLayeredPane();
rightPanel.setBounds(0,0,900,600);
splitPane.setBounds(0,0,900,600);
layeredPane.add(rightPanel,0,0); //Main Content is behind the split pane
layeredPane.add(splitPane, 1,0);
I am seeing the splitPane with the left panel as it should be but the right panel is white, switching the layers on the layeredPane I do see my (non white) main panel.
Changing the background color of the right panel I realized that the white is indeed the transparent panel and the problem is that the panel behind it isn't showing. What am I missing?
The split Pane with the non transparent right panel
What should show behind it

thanks #VGR as I was making the minimal reproducible example I found the solution, both the transparent panel and the SplitPane need to be transparent in order for the Panel behind to show
package FrontEnd;
import javax.swing.*;
import java.awt.*;
public class Problem {
public static void main(String[] args){
JFrame frame = new JFrame("test");
frame.setSize(600,600);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel left = new JPanel();
left.setBackground(Color.blue);
JPanel transparent = new JPanel();
transparent.setOpaque(false);
JSplitPane SP = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,left,transparent);
SP.setBounds(0,0,600,600);
SP.setOpaque(false);
JPanel right = new JPanel();
right.setBackground(Color.red);
right.setBounds(0,0,600,600);
JLayeredPane LP = new JLayeredPane();
LP.add(right,0,0);
LP.add(SP,1,0);
frame.add(LP);
frame.setVisible(true);
}
}
Now theoretically the right panel (red) shouldn't move around when resizing the SplitPane as that affects the left panel and the transparent panel

Related

How do I move a JLabel that is stuck and won't move?

Here is the code, when the image is put onto the background it just stays stuck to the left wall no matter what code I add to move it. I have tried setLocation and setBounds. All I want to do is move the image to the bottom left but, not fully on the walls of the frame.
JFrame window = new JFrame();
window.setSize(800,480);
window.setTitle("Battle");
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setLayout(new BorderLayout());
JLabel background = new JLabel();
ImageIcon icon = new ImageIcon("background2.png");
background.setIcon(icon);
background.setLayout(new BorderLayout());
window.setContentPane(background);
JLabel p1 = new JLabel();
p1 = a.getImage();
background.add(p1);
p1.setLocation(500,500);
p1.setVisible(true);
window.setVisible(true);
window.setLayout(new BorderLayout());
...
window.setContentPane(background);
The first statement doesn't do anything because the second statement replaces the content pane of the frame, to the layout manager will be whatever layout manager you set for the "background" component.
All I want to do is move the image to the bottom left,
Well you set the layout manager to a BorderLayout so you need to take advantage of the BorderLayout. Read the section from the Swing tutorial on How to Use BorderLayout for working examples.
So the first thing you need to do is specify the proper constraint to have the component displayed at the bottom:
//background.add(p1); // defaults to BorderLayout.CENTER if no constraint is specified
background.add(p1, BorderLayout.PAGE_END);
Test this and the image will be at the bottom, but it is still centered.
So now you need to set a property on the label to tell the label to paint itself left aligned:
label.setHorizontalAlignment(JLabel.LEFT);
not fully on the walls of the frame
If you need extra space around the image then you can add a Border to the label. Using the above link read the section from the tutorial on How to Use Borders. You can use an EmptyBorder to give the extra space.
One way to do this would be to add extra "left panel" container so we can position your label on the left and bottom
public static void main(String[] args) {
JFrame window = new JFrame();
window.setSize(800, 480);
window.setTitle("Battle");
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel background = new JLabel();
background.setBackground(Color.gray);
background.setLayout(new BorderLayout());
background.setOpaque(true);
window.setContentPane(background);
JPanel leftPanel = new JPanel();
leftPanel.setLayout(new BorderLayout());
background.add(leftPanel, BorderLayout.WEST); // stick our left side bard to the left side of frame
JLabel p1 = new JLabel();
p1.setText("Im here");
p1.setLocation(500, 500);
p1.setVisible(true);
p1.setBackground(Color.black);
p1.setOpaque(true);
leftPanel.add(p1, BorderLayout.SOUTH); // add our label to the bottom
window.setVisible(true);
}
Results:

Panel over a GridLayout Panel

Is it possible to show a Panel (e.g. Panel-A which is nearly transparent) over a panel that has a GridLayout of images?
JPanel mainPanel = new JPanel(new BorderLayout());
JPanel gridOfImages = new JPanel(new GridLayout(3,3));//Panel with a grid of images
JPanel nearlyOpaquePanel = new JPanel(); //A panel that is almost transparent.
// assuming that all already have the required properties like size and colour.
mainPanel.add(gridOfImages,Borderlayout.CENTER);
mainPanel.add(nearlyOpaquePanel,BorderLayout.CENTER);
My thought with this idea is that the panels will stack together and the gridOfImages will be shown through the nearlyOpaquePanel, but my result is that I only got the nearlyOpaquePanel to show and I can't see the gridOfImages through it.
See How to Decorate Components with the JLayer Class

Best layout for frame

What kind of layout should I use to create a page Like this:
It should be resizable
It has two main panels Right and Left?
Extra space will be given to the 'Main Text' text area, and extra height will be given to the button panel while centering them.
import java.awt.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
public class EndOfLineButtonLayout {
public static void main(String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
// the GUI as seen by the user (without frame)
JPanel gui = new JPanel(new BorderLayout());
gui.setBorder(new EmptyBorder(2, 3, 2, 3));
JPanel textPanel = new JPanel(new BorderLayout(5,5));
textPanel.add(new JScrollPane(new JTextArea("Top Text",3,20)),
BorderLayout.PAGE_START);
textPanel.add(new JScrollPane(new JTextArea("Main Text",10,10)));
gui.add(textPanel, BorderLayout.CENTER);
JPanel buttonCenter = new JPanel(new GridBagLayout());
buttonCenter.setBorder(new EmptyBorder(5,5,5,5));
JPanel buttonPanel = new JPanel(new GridLayout(0,1,5,5));
for (int ii=1; ii<6; ii++) {
buttonPanel.add(new JButton("Button " + ii));
}
// a component added to a GBL with no constraint will be centered
buttonCenter.add(buttonPanel);
gui.add(buttonCenter, BorderLayout.LINE_END);
JFrame f = new JFrame("Demo");
f.add(gui);
// Ensures JVM closes after frame(s) closed and
// all non-daemon threads are finished
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
// See http://stackoverflow.com/a/7143398/418556 for demo.
f.setLocationByPlatform(true);
// ensures the frame is the minimum size it needs to be
// in order display the components within it
f.pack();
// should be done last, to avoid flickering, moving,
// resizing artifacts.
f.setVisible(true);
}
};
// Swing GUIs should be created and updated on the EDT
// http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html
SwingUtilities.invokeLater(r);
}
}
You can use gridbag layout, try using netbeans, I have tried it and found really usefull.
Once you create it with netbeans you can use the same and build infact any kind of layout.
best of luck with other solutions.
p.s. border layout is perfect for your requirement, but I mentioned this just in case you would like to do lot more .
I would use BorderLayout.
Create Three JPanels and add them to a JFrame as follows:
public class YourClass extends JFrame{
//code here
this.setLayout(new BorderLayout());
this.add(TopPanel, BorderLayout.NORTH);
this.add(RightPanel, BorderLayout.EAST);
this.add(MainPanel, BorderLayout.CENTER);
this.pack();
this.setVisible(true);
The two main panels would be placed inside a main JPanel using a BorderLayout. The left panel would be placed using BorderLayout.CENTER, and the right panel would be placed using BorderLayout.LINE_END.
The left panel would use a BoxLayout, Y axis to separate the two JPanels within the left panel.
The right buttons panel would use a GridBagLayout. This sizes the buttons the same and allows you to use Insets to add some spacing to the buttons.
The buttons would be spaced from the top to the bottom of the right buttons panel. If you want all the buttons towards the top of the right buttons panel, you would put the right buttons panel inside of another JPanel using a FlowLayout.

JTabbedPane in JPanel?

I have a simple problem when I want to add tabs in my jpanel. The alignment of the tabs get horizontal instead of vertical, wich looks like crap =/.
It looks like this:
If I discard the panel instead and add the tabbedPane directly to the frame, everything works fine.
If you uncomment the three lines of code and remove the getContentPane().add(jtp); you can reproduce my probleme.
working Code:
public class TabbedPane extends JFrame
{
public TabbedPane()
{
setTitle("Tabbed Pane");
setSize(300, 300); // set size so the user can "see" it
JTabbedPane jtp = new JTabbedPane();
// JPanel panel = new JPanel();//uncomment all three lines
// panel.add(jtp);
// getContentPane().add(panel);
getContentPane().add(jtp);//remove me
JPanel jp1 = new JPanel();// This will create the first tab
JPanel jp2 = new JPanel();// This will create the second tab
JLabel label1 = new JLabel();
label1.setText("This is Tab 1");
jp1.add(label1);
jtp.addTab("Tab1", jp1);
jtp.addTab("Tab2", jp2);
JButton test = new JButton("Press");
jp2.add(test);
setVisible(true); // otherwise you won't "see" it
}
public static void main(String[] args)
{
TabbedPane tab = new TabbedPane();
}
}
Thanks a lot!
If I discard the panel instead and add the tabbedPane directly to the frame, everything works fine.
The default layout of JPanel is FlowLayout, which "lets each component assume its natural (preferred) size." The default layout of JFrame is BorderLayout, the CENTER of which ignores preferred size. In either case, invoking setSize() precludes the layout from functioning initially; re-size the frame to see the effect. Instead, use pack(), which "Causes this Window to be sized to fit the preferred size and layouts of its subcomponents."
setDefaultCloseOperation(EXIT_ON_CLOSE);
pack();
setVisible(true); // otherwise you won't "see" it
There are many things I would change in that code, starting with the recommendations of #trashgod. OTOH this is the minimal change needed in order to stretch the tabbed pane to the width/height of the parent container.
// give the panel a layout that will stretch components to available space
JPanel panel = new JPanel(new GridLayout());//uncomment all three lines
panel.add(jtp);
getContentPane().add(panel);
//getContentPane().add(jtp);//remove me
For more details see this answer.
Well firstly you can try this:
JPanel panel = new JPanel();//uncomment all three lines
panel.setLayout(new GridLayout());
JPanel jp1 = new JPanel();// This will create the first tab
JPanel jp2 = new JPanel();// This will create the second tab
JLabel label1 = new JLabel();
label1.setText("This is Tab 1");
jp1.add(label1);
jtp.addTab("Tab1", jp1);
jtp.addTab("Tab2", jp2);
JButton test = new JButton("Press");
jp2.add(test);
getContentPane().add(jtp);
and in the main:
TabbedPane tab = new TabbedPane();
tab.pack();
tab.setVisible(true);
May I suggest using MigLayout to set layouts, it will make your life easier. Hope it helps.
Try GridbagLayout. Once you have mastered it, you can design UI of any sort with this layout.
I agree with prasanth regarding the use of GridBagLayout
I have gone through this problem once and I solved it by adding the JTabbedPaneto the panel via GridBagLayout, make sure you add the JTabbedPane using the ipadx and ipady according to your requirements in your GridBagConstraints object
e.g.
JPanel myPanel=new JPanel();
myPanel.setLayout(new GridBagLayout());
JTabbedPane jTP=new JTabbedPane();
jTP.add("Tab1",new JPanel());//substitute your component instead of "new JPanel"
GridBagConstraints myConstraints=new GridBagConstraints();
myConstraints.ipadx=400;//streches the component being added along x axis - 200 px on both sides
myConstraints.ipady=600;//streches the component being added along y axis - 200 px on both sides
myPanel.add(jTP,myConstraints);
You can adjust both these properties according to what is perfect for your need

Resizing a JScrollPane based on window size

After much searching, I hope this will bring me an answer.
Ok, I have a JFrame, which has a a JPanel across the top, and one across the bottom. It also has one on the side, which contains a JScrollPane. The top and bottom panels should remain a consistent size with the window resizing, but the side panel should change vertically. Unfortunately, no scrollbar shows up at all when the JScrollPane has too many items. Rather, the entire window is enlarged, pushing the bottom panel and all excess within the JScrollPane off-screen.
I have been using MigLayout, but if I need to use another layout for the side panel I can. Here is my most recent failed iteration of code.
This is where I add the JScrollPane:
public MenuPanel(){
this.setLayout(new BorderLayout());
innerPanel = new InnerPanel();
jsp = new JScrollPane(innerPanel,
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
this.add(jsp, BorderLayout.CENTER);
}
This is inside the main window:
private void addSideSelectionPane() {
side = new SelectionPanel();
this.add(side, "wmax 200, growy");
}
And here is the code where I create the main window:
public InsWindow(){
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setExtendedState( this.getExtendedState()| java.awt.Frame.MAXIMIZED_BOTH );
this.setLayout(new MigLayout("debug, nogrid, fill", "[grow, fill]", "[pref!]10[grow, fill]"));
this.addTestLabel();
this.addSideSelectionPane();
this.addMainWindow();
this.addBottomPanel();
this.setVisible(true);
}

Categories