For some reason even though I have implemented the validate method in my code, and added my JPanel to my JFrame. I am also trying to get my JLabel to have Comic Sans font and for it to be centered in the screen. Why is my JLabel not showing up on my JPane
package math_program;
import java.awt.Color;
import java.awt.Font;
import java.util.Random;
import javax.swing.*;
import static javax.swing.JFrame.EXIT_ON_CLOSE;
public class Canvas
{
Images obj = new Images();
public void paintFrame()
{
//Instantiation of objects
Random gen = new Random();
JFrame frame = new JFrame();
JPanel panel = new JPanel();
//Text
JLabel problem = new JLabel();
frame.setVisible(true);
frame.setAlwaysOnTop(true);
frame.setResizable(false);
frame.setDefaultCloseOperation(EXIT_ON_CLOSE); //Make frame actually closeable
frame.setTitle("Math Owl: Alpha V:0.1 (coded by John)");
frame.setSize(800, 500);
frame.setLocationRelativeTo(null);
frame.add(panel); //Add JPanel to JFrame
panel.setVisible(true);
panel.setLayout(null);
panel.setBackground(Color.WHITE); //To see if text is even appearing
//Adding Components
problem.setFont(new Font("Comic Sans MS", Font.PLAIN, 20));
problem.setLocation(400,250);
problem.setText(gen.nextInt(11) + " + " + gen.nextInt(11));
panel.add(problem);
panel.validate();
}
}
Use a proper Layout Manager just as copeg said. Even the default Layout Manager (Flow Layout) will work. Just remove panel.setLayout(null); and your JLabel will show up.
Also when I try your snippet code there also problem on Images obj = new Images(); I assume you already have the Images class defined in your package somehow.
`
//frame.add(panel);
frame.setContentPane(panel);
//panel.setVisible(true); // not necessary code
//panel.setLayout(null); // not necessary code
panel.setBackground(Color.WHITE); //To see if text is even appearing
frame.getContentPane().add(problem);
The problem is that with null layout, you have to set both the location and the size of each component. You set only the location of the label, so you can fix it with problem.setSize(x, y);. With that being said, it's just wrong to take this approach. See what your whole GUI design for this frame looks like and choose an appropriate LayoutManager.
Try this:
public class MyCanvas {
public MyCanvas() {
Random gen = new Random();
JFrame frame = new JFrame();
JPanel panel = new JPanel();
JLabel problem = new JLabel();
panel.setBackground(Color.WHITE);
problem.setFont(new Font("Comic Sans MS", Font.PLAIN, 20));
problem.setText(gen.nextInt(11) + " + " + gen.nextInt(11));
panel.add(problem); // Default FlowLayout
frame.add(panel); // Default BorderLayout at position CENTER
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("Math Owl: Alpha V:0.1 (coded by John)");
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
new MyCanvas();
}
}
Notes:
frame.setVisible(true) should be the last call you make.
frame.setAlwaysOnTop(true) and frame.setResizable(false) are things you usually want to avoid from the user's perspective.
frame.setSize(...) should be replace with frame.pack().
frame.setLocationRelativeTo(null) should be called between pack() and setVisible(true).
No need for panel.setVisible(true), it does nothing for you.
No need for panel.validate() (should be revalidate()), it is only needed when changing the layout during runtime.
The class Canvas already exists, use a different name.
There two way
is you are using any layout manager then you can simply show the component by using setSize(new Dimension(width, height)
if you have set the layout manager to null then you must use
setBounds(x,y, width, height) (if you do this obviously no need to set size) to show the component
otherwise just do
setSize(new Dimension(width,height)
then setLocation(x,y)
if you want to dynamically calculate the position then you can set the initial locaion as setLocation(0,0)
afterwards when all the components are showing you can use your algorithm to recalculate x and y position and again setLocation(x,y)
for e.g.
label1=setSize(new Dimension(100,20)
label1.setLocation(0,0)
Label2=setSize(new Dimension(100,20)
Label2.setLocation((int)label1.getSize().getWidth()+10,20) and so on
Related
So basically when I add a button it essentially pushes the black rectangle drawn in this program down, putting it out of its given location. How would you fix this?
import javax.swing.*;
import java.awt.*;
public class Grid {
public class homeGraphics extends JComponent {
homeGraphics() {
setPreferredSize(new Dimension(450, 600));
}
public void paint(Graphics g) {
super.paint(g);
g.fillRect(200, 275, 50, 50);
}
}
public void homeFrame() {
JFrame frame1 = new JFrame();
frame1.setSize(450, 600);
frame1.setResizable(false);
frame1.setDefaultCloseOperation(frame1.EXIT_ON_CLOSE);
JButton playButton = new JButton("Play");
playButton.setPreferredSize(new Dimension(60, 30));
JPanel panel1 = new JPanel();
panel1.add(playButton);
panel1.add(new homeGraphics());
frame1.add(panel1);
frame1.setVisible(true);
}
public static void main(String args[]) {
Grid frame = new Grid();
frame.homeFrame();
}
}```
it essentially pushes the black rectangle drawn in this program down, putting it out of its given location.
What do you mean out of its location? Painting is always done relative to the component. So your painting will always be done at (200, 275) of the component.
If you are attempting to paint at (200, 275) relative to the "frame", then don't. That is NOT how painting works.
Other problems with your code:
Don't attempt to set the size of your frame. If the custom panel is (450, 600) how can the frame possibly be the same size? The frame also contains the "title bar" and "borders". Instead of using setSize(), you invoke frame.pack()just beforeframe1.setVisible(….)`.
Class names start with an upper case character. Learn by example. Have you ever seen a class name in the JDK that doesn't start with an upper case character?
Custom painting is done by overriding paintComponent(…), not paint().
By default a JPanel uses a FlowLayout. So what you see it the button on one line and then the "HomeGraphics" class is too big to fit on the same line so it wraps the to the second line.
You should be more explicit when you do frame layout. So your code should be something like:
JPanel wrapper = new JPanel();
wrapper.add( playButton );
//JPanel panel1 = new JPanel();
//panel1.add(playButton);
//panel1.add(new homeGraphics());
JPanel panel1 = new JPanel( new BorderLayout() );
panel1.add(wrapper, BorderLayout.PAGE_START);
panel1.add(new HomeGraphics(), BorderLayout.CENTER);
Now the code shows your layout attempt more clearly.
I am creating a simple Window in GridLayout and here is my code:
package com.company.app;
import javax.swing.*;
import java.awt.*;
public class SpamGUI {
public static void main(String[] args) {
System.out.println("Loading Program..");
JFrame frame = new JFrame("My awesome Program");
frame.setVisible(true);
frame.setSize(800, 200);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(0, 3));
panel.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
JLabel lblTrainPath = new JLabel("Enter Training Folder Path");
lblTrainPath.setSize(100,10);
panel.add(lblTrainPath);
JTextField txtTrainPath = new JTextField();
txtTrainPath.setSize(100,10);
panel.add(txtTrainPath);
JButton btnTrainPath = new JButton("Select");
panel.add(btnTrainPath);
JLabel lblTrainPath3 = new JLabel("Enter Training3 Folder Path");
panel.add(lblTrainPath3);
JTextField txtTestPath = new JTextField();
panel.add(txtTestPath);
JButton btnTestPath = new JButton("Select");
panel.add(btnTestPath);
frame.add(panel);
}
}
It generates screen like this:
As you can see,it is not respecting size of components, showing quite broad on screens. Also when I run program from INtelliJ IDEA, it does not render components unless I resize screen.
I also want a fixed size window having component with custom size.
Please guide
The Font class allows you to specify font size.
So, to create a font you should code like this:
Font f = new Font("serif", Font.PLAIN, fontSize);
The fontSize parameter will determine the size of the Font
So, here enter font size you want ..after that set that font instance variable f to your JLabel instance variable like this:
lblTrainPath.setFont(f);
and for having component with custom size.
you should try pack() instead of frame.setSize(800,200)
and use this pack() after adding all the components to your frame and for fixed size window use setResizable(false)...
Hello guys it's me again with another question. So I have this program and I basically did what it was supposed to do, but I'm not really implementing the idea of a scroll panel in the program which I should be, because the dimensions for the scroll panel is very large. I only made it large because that's the way I can have my invisible button there without it moving. How can I make my invisible button stay at a particular place of the image instead of layout if you understand what I'm saying? I want the button to stay at a certain point on the image, not on the layout so that If I move the scroll Panel dimensions, it moves with it. sorry If i am bad at explaining things here is my code. Thank you for taking the time to read this.
import java.awt.*;
import javax.swing.*;
public class TransitMap
{
//-----------------------------------------------------------------
// Presents a frame containing a scroll pane used to view a large
// map of the New York transit system.
//-----------------------------------------------------------------
public static void main(String[] args)
{
JFrame frame = new JFrame("New York Transit Map");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//frame.setLayout(null);
//frame.setPreferredSize(new Dimension(900, 900));
JPanel mainPane = new JPanel();
mainPane.setLayout(null);
mainPane.setPreferredSize(new Dimension(1300,800));
ImageIcon image = new ImageIcon("fortress.jpg");
JLabel imageLabel = new JLabel(image);
JScrollPane sp = new JScrollPane(imageLabel);
sp.setPreferredSize(new Dimension(400, 400));
sp.setBounds(0, 0, 1300, 800);
JButton button = new JButton("test");
button.setBounds(640,360,50,50);
button.setOpaque(false);
button.setContentAreaFilled(false);
button.setBorderPainted(false);
button.setToolTipText("<html><img src=\"" +
TransitMap.class.getResource("Bala_Hissar.jpg") +
"\"> <br> This is the fortress ");
mainPane.add(button);
mainPane.add(sp);
frame.getContentPane().add(mainPane);
frame.pack();
frame.setVisible(true);
}
}
I have tried looking at many documentations and tutorials but none of them seem to work together. I am just trying to make a simple "main menu" for a "game" my friend and I are attempting to make. I am able to move the buttons around when there is no background image present, and I am only able to get the background image but I can't move the buttons around.
So my question is how can I position JButtons?
Here is my code & a screenshot:
What my frame looks like
package game;
import java.awt.FlowLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class MainMenu extends JFrame{
private JButton singPlay = new JButton("Single Player");
private JButton twoPlay = new JButton("Two Player");
public MainMenu()
{
JFrame frame = new JFrame("TestTEST");
JPanel panel = new JPanel();
frame.setSize(400,500);
frame.setLocation(700,300);
frame.setResizable(false);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(new JLabel(new ImageIcon("C:\\Users\\Austin\\Pictures\\Landscape.jpg")));
frame.setLayout(new FlowLayout());
frame.add(singPlay);
frame.add(twoPlay);
frame.setSize(399,499);
frame.setSize(400, 500);
}
public static void main(String[] args)
{
new MainMenu();
}
}
So my question is how can I position JButtons?
Use an appropriate layout manager.
You set the layout manager to a FlowLayout so the buttons are displayed at the top of the frame.
Maybe you want to center the buttons on the frame. If so then you can use a GridbagLayout.
Also, don't use setSize(). Use the pack() method. Finally the frame should be made visible AFTER you add the components to the frame.
So your code might look something like:
public MainMenu()
{
JPanel panel = new JPanel();
panel.setOpaque(false);
panel.add(singPlay);
panel.add(twoPlay);
JFrame frame = new JFrame("TestTEST");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.setContentPane(new JLabel(new ImageIcon("yourfilename.jpg")));
frame.setLayout(new GridBagLayout());
frame.add(panel, new GridBagConstraints());
frame.pack();
frame.setLocationRelativeTo( null );
frame.setVisible( true );
}
Or maybe you want the buttons centered vertically. Then you can use a vertical BoxLayout.
Read the Swing tutorial on Layout Managers and decide for yourself what is appropriate.
Right now you're using a JLabel as a content pane, which doesn't make a ton of sense.
Instead of putting your background in a JLabel, you should extend JPanel and override paintComponent() to draw the background yourself. Here is a great tutorial on performing custom painting.
Once you have your background JPanel, put your JButtons inside that and use it as your content pane.
After that, if you're looking to manually position your JButtons, then you might be looking for a null layout.
JFrame.setContentFrame() is not how you set a background image. See the selected answer at How to set background image in Java?
Also, you should be doing all these operations in the Swing event thread.
public static void main(String [] args) {
SwingUtilities.invokeLater( new Runnable() {
public void run() {
new MainMenu();
}
});
}
A simple solution is to use GridBagLayout, the following will centre the buttons, on on top of each, vertically and horizontally in the container
public MainMenu() {
JFrame frame = new JFrame("TestTEST");
JPanel panel = new JPanel();
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(new JLabel(new ImageIcon("C:\\Users\\Austin\\Pictures\\Landscape.jpg")));
frame.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.insets = new Insets(4, 4, 4, 4);
gbc.fill = GridBagConstraints.HORIZONTAL; frame.add(singPlay, gbc);
frame.add(twoPlay, gbc);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
As a side note, while JLabel work in this case, you need to be ware that it will calculate it's preferred size from the icon (and text) properties of the label itself, not it's children, JLabel really wasn't designed to hold other components
I want to show a textArea showing some text (will show log lines) , and have an animated gif hoovering above it. I tried the solution described here , but all I get is a grey screen. Hints?
public class TestLayeredPanes {
private JFrame frame = new JFrame();
private JLayeredPane lpane = new JLayeredPane();
public TestLayeredPanes() {
frame.setPreferredSize(new Dimension(600, 400));
frame.setLayout(new BorderLayout());
frame.add(lpane, BorderLayout.CENTER);
//Build the animated icon
JLabel buildingIcon = new JLabel();
buildingIcon.setIcon(new ImageIcon(this.getClass().getResource(
"/com/ct/tasks/cmviewer/gui/progress_bar.gif")));
JPanel iconPanel = new JPanel();
iconPanel.add(buildingIcon);
//Build the textArea
JTextArea textLog = new JTextArea("Say something");
JPanel textPanel = new JPanel();
textPanel.add(new JScrollPane(textLog));
//Add the panels to the layered pane
lpane.add(textPanel, 0);
lpane.add(iconPanel, 1);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
new TestLayeredPanes();
}
}
Try putting your animated GIF on the glass pane of your root pane:
http://download.oracle.com/javase/tutorial/uiswing/components/rootpane.html
JXLayer make easier to do that. Look at JXLayer samples.
You also can take a look at code of XSwingX
Since you started with a working example, why did you remove lines of code from the example you copied?
Layered panes don't use a layout manager therefore the size of your components are (0, 0), so there is nothing to display. The setBounds(...) method in the example are there for a reason.