I have a Gui I'm making for a program that has an outer container centered to the JFrame that contains an inner container that holds 22*12 cells. When I run this program, the background just flickers white and stays like that. If you could point me out where I'm going wrong that would be awesome!
public class Gui extends JFrame
{
private JPanel outer, inner;
private JLabel[][] labels = new JLabel[22][12];
public Gui()
{
setBackground(Color.black);
setSize(1000,1000);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new BorderLayout());
outer = new JPanel();
outer.setLayout(new BorderLayout());
outer.setSize(620,920);
outer.setBackground(Color.white);
inner = new JPanel();
inner.setLayout(new GridLayout(22,12,10,10));
inner.setSize(600,900);
inner.setBackground(Color.white);
for (int i = 0; i < 22; i++)
{
for (int j = 0; j < 12; j++)
{
labels[i][j] = new JLabel();
JLabel label = labels[i][j];
label.setSize(50,50);
label.setBackground(Color.gray);
inner.add(label);
}
}
outer.add(inner, BorderLayout.CENTER);
add(outer, BorderLayout.CENTER);
}
}
The gui is set visible in the main class that instantiates it.
The gui is created and sized correctly. It starts out with a black background then randomly turns to white just after and stays like that.
EDIT: if this is still important:
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
Gui gui = new Gui();
gui.setVisible(true);
}
});
}
Use the new static variable names which follow final static naming convention. That is the variable should be upper cased:
//setBackground(Color.black);
setBackground(Color.BLACK);
Don't use setSize() for components. Instead add the components to the frame and then use the pack() method so the components are displayed at their preferred size:
//setSize(1000,1000);
add(component1);
add(anotherComponent);
pack();
Layout managers use the preferred size not the size as a layout tip:
//label.setSize(50,50);
label.setPreferredSize(new Dimension(50, 50));
This is your main problem. A JLabel is transparent by default, so the background color you set is ignored:
label.setBackground(Color.gray);
label.setOpaque(true);
By the way, my screen height is only 738, so won't event be able to see you entire frame since you want a height of 22*50. You should be aware of this and probably add your panel to a JScrollPane so people like me can actually use your application. This is why you should not hardcode a preferred size.
Related
i been working on some bigger project lately but couldn't figure it out why JScrollPane wouldn't work. I have never used it before and I read many solved problems about it on stackOverflow and other programming forums but non of the code were looking similar to mine to help me implement my method.
this is new project i made to make it short and show some examples.
Red colour is main panel that will contain another panel/JScrollPane inside that will be colour black
and i would like to make this Jpanel with colour black to be scrollable and hold any number of that white JPanels that might be from 0 to a 100+
public class ScrollablePane {
private JFrame frame;
private JPanel panelCopy;
private JPanel panel;
private JPanel container;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
ScrollablePane window = new ScrollablePane();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public ScrollablePane() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
panel = new JPanel();
panel.setBackground(Color.RED);
panel.setBounds(0, 0, 434, 261);
frame.getContentPane().add(panel);
panel.setLayout(null);
container = new JPanel();
container.setBackground(Color.BLACK);
container.setBounds(10, 10, 414, 241);
container.setLayout(new FlowLayout(FlowLayout.CENTER, 10, 10));
panel.add(container);
for(int i = 0; i < 20; i++) {
if(i > 0) {
panelCopy = new JPanel();
panelCopy.setPreferredSize(new Dimension(400, 40));
container.add(panelCopy);
}
}
}
}
if you want to use a JScrollPane, then your code actually needs to use a JScrollPane. The code you posted doesn't even create a JScrollPane.
If you want the panels to display vertically then don't use a FlowLayout. The FlowLayout is a horizontal layout. You could use a BoxLayout or a GridBagLayout.
Why do you create the "panel" variable and add it the the content pane? The content pane of the frame already is a JPanel that uses a BorderLayout. There is no need to add another panel
Don't use a null layout!!! Swing was designed to be used with layout managers. Scrolling won't work if the panel added to the scroll pane uses a null layout.
So in your case the basic logic might be something like:
Box container = Box.createVerticalBox();
// add you child panels to the container.
JPanel wrapper = new JPanel( new BorderLayout() );
wrapper.add(container, BorderLayout.PAGE_START);
JScrollPane scrollPane = new JScrollPane(wrapper);
frame.add(scrollPane, BorderLayout.CENTER);
Note the "wrapper" panel is used to prevent the panels from expanding in size when the scroll pane is larger then the preferred size of the "container" panel.
Try:
//JScrollPane scrollPane = new JScrollPane(wrapper);
JScrollPane scrollPane = new JScrollPane(container);
to see the different result.
When I run this program it appears as an empty window until you fullscreen, then it can be resized as you like, why is it doing this/how do I stop it?
the program is very basic just a menubar and two panels split.
public class SplitPane {
public static void main(String[] args) {
window view = new window();
}
private static class window extends JFrame {
public window() {
this.setSize(1000, 750);
this.setVisible(true);
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
//menubar is here, must lower code quantity for stack
//panels
//graph half
JPanel graphRep = new JPanel();
//Background colour - graphRep.setBackground(Color.RED);
graphRep.setVisible(true);
String graphTitle = "Textual Representation.";
Border graphBorder = BorderFactory.createTitledBorder(graphTitle);
graphRep.setBorder(graphBorder);
//text half
JPanel textRep = new JPanel();
textRep.setVisible(true);
String textTitle = "Graphical Representation.";
Border textBorder = BorderFactory.createTitledBorder(textTitle);
textRep.setBorder(textBorder);
//splitpane
JSplitPane splitPane = new JSplitPane();
splitPane.setSize(600, 750);
splitPane.setOrientation(JSplitPane.HORIZONTAL_SPLIT);
splitPane.setOneTouchExpandable(true);
splitPane.setDividerSize(10);
splitPane.setDividerLocation(250);
splitPane.setLeftComponent(graphRep);
splitPane.setRightComponent(textRep);
this.add(splitPane);
}
}
this.setVisible(true);
You are making the frame visible BEFORE you add components to the frame. The layout manager is never invoked so the size of all the components remains (0, 0) so there is nothing to paint.
The frame should be made visible AFTER all the components have been added to the frame.
And the code should be:
frame.pack();
frame.setVisible();
So each component is displayed at its proper size. Don't hardcode the size() because you don't know what the size of a users screen might be.
I am trying to place a JPanel on top of another JPanel which contains a JTextArea and a button and i want to the upper apnel to be transparent. I have tried it by making the setOpaque(false) of the upper panel. but it is not working. Can anyone help me to get through this? Thanks in advance!
public class JpanelTest extends JPanel
{
public JpanelTest()
{
super();
onInit();
}
private void onInit()
{
setLayout(new BorderLayout());
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
panel.add(new JTextArea(100,100),BorderLayout.CENTER);
panel.add(new JButton("submit"),BorderLayout.SOUTH);
JPanel glass = new JPanel();
glass.setOpaque(false);
add(panel,BorderLayout.CENTER);
add(glass,BorderLayout.CENTER);
setVisible(true);
}
public static void main(String args[])
{
new JpanelTest();
}
}
Indeed, it would be useful to tell the reason why you want panels one over another.
Starting with your code, and changing it a lot, I got it to work, but it might not do what you expect...
import java.awt.*;
import javax.swing.*;
public class Test extends JFrame
{
public Test()
{
super();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(500, 200);
onInit();
setVisible(true);
}
private void onInit()
{
JLayeredPane lp = getLayeredPane();
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
panel.add(new JTextArea(), BorderLayout.CENTER);
panel.add(new JButton("Submit"), BorderLayout.SOUTH);
panel.setSize(300, 150); // Size is needed here, as there is no layout in lp
JPanel glass = new JPanel();
glass.setOpaque(false); // Set to true to see it
glass.setBackground(Color.GREEN);
glass.setSize(300, 150);
glass.setLocation(10, 10);
lp.add(panel, Integer.valueOf(1));
lp.add(glass, Integer.valueOf(2));
}
public static void main(String args[])
{
// Schedule a job for the event-dispatching thread:
// creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new Test();
}
});
}
}
If totally transparent, well, it is like it isn't here! When opaque, it just covers some of the GUI, but doesn't prevent mouse clicks, for example.
1) there are a few ways, there no issue to put JPanel, with covering full JFrames/JPanel area or only part of Rectangle / Dimension that returns JFrames/JPanel
use JLayer(Java7) based on JXLayer (Java6)
use GlassPane
use JViewport
use OverlayLayout
use transucent JDialog / JWindow
2) everything depends of if you want to protect against mouse and key events from the top layer to bottom, or not (to avoiding redispatch events from - to and vice versa)
Check out this tutorial on using Swing Root Panes.
The glass pane is useful when you want to be able to catch events or paint over an area that already contains one or more components. For example, you can deactivate mouse events for a multi-component region by having the glass pane intercept the events. Or you can display an image over multiple components using the glass pane.
I was wondering the following: I have a MainWindow component (which contains a frame (JFrame)) and several other JPanels. Where one JPanel, let's say gridPanel uses the gridLayout as LayoutManager. Now my problem is that I want to adjust (set the size of rows / set the size of columns) after the window has been resized. Can someone tell me how I can achieve actions that can be triggered after resizing the frame as I am not familiar with the listeners involved.
It should be the done on the most "standard" coding practices. Thank you for your response and answers!
If you want your grid to "fill up" a container, or fill up the JFrame, then key is to use proper layout managers to hold the GridLayout-using container. For instance if you add the GridLayout-using container to another container that uses FlowLayout, then the GridLayout-using container will not change size if its holding container changes size. However if you add the GridLayout-using container to another container that uses BorderLayout and to its BorderLayout.CENTER position, then the GridLayout-using container will resize as the BorderLayout-using parent container resizes.
Example:
import java.awt.*;
import javax.swing.*;
#SuppressWarnings("serial")
public class ExpandingGrid extends JPanel {
private static final int GAP = 5;
public ExpandingGrid() {
// create a BorderLayout-using JPanel
JPanel borderLayoutPanel = new JPanel(new BorderLayout());
borderLayoutPanel.setBorder(BorderFactory.createTitledBorder("BorderLayout Panel"));
borderLayoutPanel.add(createGridPanel(), BorderLayout.CENTER); // add a Grid to it
// create a FlowLayout-using JPanel
JPanel flowLayoutPanel = new JPanel(new FlowLayout());
flowLayoutPanel.setBorder(BorderFactory.createTitledBorder("FlowLayout Panel"));
flowLayoutPanel.add(createGridPanel()); // add a grid to it
// set up the main JPanel
setBorder(BorderFactory.createEmptyBorder(GAP, GAP, GAP, GAP));
setLayout(new GridLayout(1, 0, GAP, 0)); // grid with 1 row
// and add the borderlayout and flowlayout using JPanels to it
add(borderLayoutPanel);
add(flowLayoutPanel);
}
// create a JPanel that holds a bunch of JLabels in a GridLayout
private JPanel createGridPanel() {
int rows = 5;
int cols = 5;
JPanel gridPanel = new JPanel(new GridLayout(rows, cols));
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
// create the JLabel that simply shows the row and column number
JLabel label = new JLabel(String.format("[%d, %d]", i, j),
SwingConstants.CENTER);
// give the JLabel a border
label.setBorder(BorderFactory.createEtchedBorder());
gridPanel.add(label); // add to the GridLayout using JPanel
}
}
return gridPanel;
}
private static void createAndShowUI() {
JFrame frame = new JFrame("ExpandingGrid");
frame.getContentPane().add(new ExpandingGrid());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
createAndShowUI();
}
});
}
}
Also, if this is not helpful, then you may wish to elaborate more on your problem and post code, preferably an SSCCE.
That's why I wanted to only adjust the columns.
Maybe the Wrap Layout is what you are looking for.
Why my JFrame 'frame' is diplaying empty window, when it should give me 3 menu buttons and my own painted JComponent below ? What am I missing here ?
import java.awt.*;
import javax.swing.*;
public class Eyes extends JFrame {
public static void main(String[] args) {
final JFrame frame = new JFrame("Eyes");
frame.setPreferredSize(new Dimension(450, 300));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel players = new JPanel(new GridLayout(1, 3));
players.add(new JButton("Eyes color"));
players.add(new JButton("Eye pupil"));
players.add(new JButton("Background color"));
JPanel eyes = new JPanel();
eyes.add(new MyComponent());
JPanel content = new JPanel();
content.setLayout(new BoxLayout(content, BoxLayout.Y_AXIS));
content.add(players);
content.add(eyes);
frame.getContentPane();
frame.pack();
frame.setVisible(true);
}
}
class MyComponent extends JComponent {
public MyComponent(){
}
#Override
public void paint(Graphics g) {
int height = 120;
int width = 120;
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
BasicStroke bs = new BasicStroke(3.0f);
g2d.setStroke(bs);
g2d.setColor(Color.yellow);
g2d.fillOval(200, 200, height, width);
g2d.setColor(Color.black);
g2d.drawOval(60, 60, height, width);
}
}
Your line:
frame.getContentPane();
doesnt do anything but access the content pane of the frame. Instead of getting the content pane, you should set your content pane, like this:
frame.setContentPane(content);
EDIT:
alternatively, as #trashgod points out, you could use the getContentPane method to access the default content pane and add your content component to that:
frame.getContentPane().add(content);
I think you are attempting to use nested JPanels. This is certainly a way to organize your components, but downside to is the fact that it gets difficult to manage in some cases. You could try this snippet of code below. In the program you will find:
1) An array of JLabel
2) An array of JTextField
3) Nested JPanels
At the end of the program I use the Container to add the final product of these object to my Graphics Window.
The most efficient way I can think of is to define these components at the top of my program so that I can reuse them later as I need to.
To achieve this you can try this snippet of code:
import javax.swing.*; //Required to use Swing Components
public class TestGUI extends JFrame
{
JLabel[] label; //Define this with an array
JTextField[] textField; //Define this with an array as well
private int nLabels; //Number of labels preferred
private int nTextFields; //Number of text fields preferred
public testGUI(int amt)
{
//Assuming that you want equal amounts of each,
//set these two variables to the "ant" input parameter
nLabels = amt;
nTextFields = amt;
//Set component attributes
label = new JLabel[2]; //Label compared text fields
textField = new JTextField[2]; //Use two of these for comparison
textField[0].setEnabled(false); //Disabled editing
//Do nothing with the second text field
JPanel labels = new JPanel(); //Place JLabels here
//Use this to align the labels vertically
labels.setLayout(new GridLayout(2, 1));
//Use this for loop to add the labels to this JPanel
for(int i = 0; i < nLabels; i++)
{
labels.add(label[i]);
//You can also define and apply additional properties
//to labels inside this loop. TIP: You can do this in
//any loop
}
JPanel txtFields = new JPanel(); //Place JTextFields here
//Use this to align the text fields vertically
txtFields.setLayout(new GridLayout(2, 1));
//Use this for loop to add the labels to this JPanel
for(int i = 0; i < nTextFields; i++)
{
textFields.add(textField[i]);
//You can also define and apply additional properties
//to text fields inside this loop. TIP: You can do
//this in any loop
}
//Now we have the two components, you asked for help with, set up
//Next, we will need another JPanel to add these to panels to.
//This JPanel will be added to the JFrame Container
//You probably know how to run this via the "main" method
JPanel window = new JPanel();
//Place the JPanel for the labels and text fields
//This requires a horizontal grid
window.setLayout(new GridLayout(1, 2));
//Add the the two JPanels: "labels" and "txtFields"
window.add(labels);
window.add(txtFields);
//Define the Container object to set up the GUI
Container container = getContentPane();
//Apply the "window" JPanel object to the container
container.add(window, BorderLayout.CENTER);
//Center this in the Graphics Window when displayed
}
//Any other methods and/or functions can be added as well
//If they are, they must placed in the constructor method above
}
This is the approach that I would use when trying to go at making and manipulating my Graphics Windows that I write. Sometimes I write applets, but only after making sure that I have everything functioning properly in a plain Graphics Window.
I hope this helps.
If you have any other questions, just let me know and I will answer the to the best of my ability, thanks.