I have a question about using JFrames
(source 1)
import javax.swing.*;
public class FirstSwingExample {
public static void main(String[] args) {
JFrame f = new JFrame();// creating instance of JFrame
JButton b = new JButton("click");// creating instance of JButton
b.setBounds(130, 100, 100, 40);// x axis, y axis, width, height
f.add(b);// adding button in JFrame
f.setSize(400, 500);// 400 width and 500 height
f.setLayout(null);// using no layout managers
f.setVisible(true);// making the frame visible
}
}
(source 2)
import javax.swing.JButton;
import javax.swing.JFrame;
class FrameTest extends JFrame {
public FrameTest() {
JButton b=new JButton("click");//create button
b.setBounds(130,100,100, 40);
add(b);//adding button on frame
setSize(400,500);
setLayout(null);
setVisible(true);
}
}
public class Appl {
public static void main(String[] args) {
new FrameTest();
}
}
My question is:
in source 1 - .add, .setSize, .setLayout and .setVisible are methods of instance of 'f'.
those of methods initialize properties of 'f'.
but in source2 - add, setSize, setLayout and setVisible are methods of a certain super class.
in this source, there are not any JFrame instance. However it just works without problems.
I cannot figure it out. I discovered Container.class and JFrame.class, Frame.class But I couldn't find the part that makes JFrame instance.
in this source, there are not any JFrame instance
This is the incorrect assumption. In the second code base the current instance, the this as it were is a JFrame object. You create the instance when you call new FrameTest(). Since FrameTest inherits from JFrame, all instances will be children of JFrame.
Other unrelated issues:
While null layouts and setBounds() might seem to Swing newbies like the easiest and best way to create complex GUI's, the more Swing GUI'S you create the more serious difficulties you will run into when using them. They won't resize your components when the GUI resizes, they are a royal witch to enhance or maintain, they fail completely when placed in scrollpanes, they look gawd-awful when viewed on all platforms or screen resolutions that are different from the original one.
You'll usually not want to create classes that extend JFrame, since in doing so you are forced to create and display JFrames, when often more flexibility is called for. In fact, I would venture that most of the Swing GUI code that I've created and that I've seen does not extend JFrame, and in fact it is rare that you'll ever want to do this. More commonly your GUI classes will be geared towards creating JPanels, which can then be placed into JFrames or JDialogs, or JTabbedPanes, or swapped via CardLayouts, wherever needed. This will greatly increase the flexibility of your GUI coding.
Related
So I'm having a class called Menu which extends JLabel and has a constructor which adds 3 JButtons to itself.
public Menu() {
this.add(jbutton1);
this.add(jbutton2);
this.add(jbutton3);
}
I have another class called GUI which extends JFrame and adds the JLabel to its contentPane.
public GUI() {
Menu menu = new Menu();
getContentPane().add(menu);
setSize(300,200);
setVisible(true);
}
The main method of GUI just looks like this:
public static void main(String[] args) {
GUI gui = new GUI();
}
So what I wanted is a JFrame with 3 JButtons in it (going to do more stuff later one). Instead I just got a blank JFrame. Why don't I see the JLabel with the 3 JButtons in it I added?
You're forgetting layout managers which are key to controlling how components are added to and sized by containers. JLabels are not used to being used as a container and holding other components and so come by default with a null layout -- no layout at all, making you the programmer responsible for sizing and positioning any added component.
Solutions:
Set your JButton's sizes and positions yourself -- a very bad solution since it leads to GUI's that only work well on one platform and that are difficult to debug and maintain
Or give the container (here the JLabel) a decent layout manager.
Or use another container, such as a JPanel, one that already has a layout manager, as the contentPanel. There are ways of getting a JPanel to display an image including overriding its paintComponent method.
You can find the layout manager tutorial here: Layout Manager Tutorial, and you can find links to the Swing tutorials and to other Swing resources here: Swing Info.
I have a problem, I set the size for frame, but doesn't work. I found a topic about this, but it's not helpful for me...
I tried with getContentPane().getSize(500,500), but nothing.
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
public class Mere extends JFrame{
private JPanel b;
public Mere(String titlu){
setSize(500,500);
setLayout(null);
this.getSmth();
pack();
show();
}
public void getSmth(){
JLabel user=new JLabel("User");
user.setBounds(10,10,80,25);
getContentPane().add(user);
JTextField userText=new JTextField(20);
userText.setBounds(100,10,160,25);
getContentPane().add(userText);
JPasswordField pas=new JPasswordField(20);
pas.setBounds(100,40,160,25);
getContentPane().add(pas);
JButton n=new JButton("Register");
n.setBounds(180,80,100,30);
getContentPane().add(n);
JLabel pass=new JLabel("Pass");
pass.setBounds(10,40,100,25);
getContentPane().add(pass);
getContentPane().setVisible(true);
}
public static void main(String[]args){
new Mere("yas");
}
}
You're calling pack(); after calling setSize().
From the Oracle docs
Causes this Window to be sized to fit the preferred size and layouts of its subcomponents. The resulting width and height of the window are automatically enlarged if either of dimensions is less than the minimum size as specified by the previous call to the setMinimumSize method.
So you rather override the getPreferredSize() method or remove the pack() call. See Should I avoid the use of setPreferred/Maximum/MinimumSize? (YES)
However the best practice would be to use a layout manager (as explanined below) and then call pack() and let the manager do it's job while calculating the preferredSize for you
Also you're using a null layout. Swing was designed to work with different PLAFs and screen sizes and resolutions, while pixel perfect GUIs might seem like the best and faster approach to make a complex GUI the more you advance in this the more problems you'll have in maintain it due to this, so go ahead and use a proper Layout Manager or combinations of them. See Null Layout is Evil and Why is it frowned upon to use a null layout in Java Swing?
Another thing is that you're not placing your program on the Event Dispatch Thread (EDT), see SwingUtilities.invokeLater() why is it needed? and this answer for an example on how to use it
Another thing I see is that you're extening JFrame which translated to english it says that your class is a JFrame, JFrame isn't flexible when you need to add it to another Component, instead you should create a JFrame instance and if you really need to extend something, extend from a JPanel.
Here's my JPanel. The first button is always visible, but the secound is visible only when you place a cursour on it. Where the problem can be?
P.S. Please use simple english, if u can, because I don't speak english well
public class GamePanel extends JPanel implements KeyListener{
GamePanel(){
setLayout(null);
}
public void paint(Graphics g){
JButton buttonShip1 = new JButton();
buttonShip1.setLocation(10, 45);
buttonShip1.setSize(40, 40);
buttonShip1.setVisible(true);
add(buttonShip1);
JButton buttonShip2 = new JButton();
buttonShip2.setLocation(110, 145);
buttonShip2.setSize(440, 440);
buttonShip2.setVisible(true);
add(buttonShip2);
}
}
If you want to avoid problems and learn Java Swing correctly, go check out their tutorials here.
There are too many problems to discuss here, so I'll try to keep it simple.
You're using a null layout. null layouts are avoided for the most part because there is usually a layout that does exactly what you want. It takes some time to get it working, but there are some defaults in this tutorial that are fairly simple to use. There are some nice pictures there that show you what you can do with each layout, too. If you use a layout manager, you generally don't need to use setLocation, setSize or setVisible on most components like JButtons.
You're calling the paint method in a Swing application. You want to call paintComponent because you're using Swing and not Awt. You also need to call the super.paintComponent(g) method on the first line of the paintComponent method in order to correctly override the other paintComponent method.
The paint/paintComponent related methods are called very often. You don't want to create/initialize objects in them. The paint/paintComponent methods aren't a one time method like they may sound. They're continuously called and you should design your GUI around this. Design your paint-related methods to be event-driven rather than sequential. In other words, program the paintComponent method with the mindset that your GUI is reacting to things continuously rather than running in sequential order like a normal program. That's a very basic approach to it and hopefully doesn't confuse you, but if you go check out that tutorial you'll see what I mean eventually.
There are two basic types of GUIs in Java. One is Swing and the
other is Awt. Check out this answer on stackoverflow for a
nice description of the two.
Here is an example of what two buttons on a JPanel look like.
public class Test
{
public static void main(String[] args)
{
JFrame jframe = new JFrame();
GamePanel gp = new GamePanel();
jframe.setContentPane(gp);
jframe.setVisible(true);
jframe.setSize(500,500);
jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static class GamePanel extends JPanel{
GamePanel() {
JButton buttonShip1 = new JButton("Button number 1");
JButton buttonShip2 = new JButton("Button number 2");
add(buttonShip1);
add(buttonShip2);
//setLayout(null);
//if you don't use a layout manager and don't set it to null
//it will automatically set it to a FlowLayout.
}
public void paintComponent(Graphics g){
super.paintComponent(g);
// ... add stuff here later
// when you've read more about Swing and
// painting in Swing applications
}
}
}
Don't use a null layout
Don't create components in a painting method. The paint() method is for custom painting only. There is no need for you to override the paint() method.
Read the section from the Swing tutorial How to Use FlowLayout for a simple example that uses buttons and a layout manager.
I have been, for a long time, wondering when to use JFrame and JPanel. I was told by textbook, in-person, and via internet search some reasons, but of course, it took me looking at the Java documentation to figure out that a JPanel has the paintComponent(Graphics); method, which allows you to specify what to do to the object itself, unlike JFrame. Also, JPanels are nestable, allowing for more complex graphics than you could achieve with just one container. I also stumbled upon the fact that a JLabel is also a container. (It even has a freaking layout!) Now my question is: when should I be using a JLabel and when should I be using a JPanel?
//I know that you can put JLabels inside a JPanel, and by accident, that a JPanel is more expensive than a JLabel. I, in the long run, plan on making a cashier game that involves some lightweight container for the "money" that moves to the customer's hand upon clicking. I was thinking about using JLabels for the monetary amounts (dollar bills and coins), and the JPanel to serve as the overhead view of the transaction(s). I was also thinking about invoking repaint() (which, to my understanding, can simulate animation) on the "money labels" themselves. This is a double-question, but would you see this as the least expensive way to go about it?
For the most part, JPanel is a container that allows for better organization. When you need to organize your components of your gui, you should use a JPanel and define a layout for the JPanel. You can also nest JPanels within each other and etc. JLabels don't have the capability of defining layouts for further components to be displayed inside the JLabel.
Here's an example of a app that says "Hello World!!!" without the quotes:
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JLabel;
public class JFrame {
public static void main (strings args[]) {
JFrame frame = new JFrame();
String title = "Hello App";
frame.setTitle(title);
frame.setSize(300, 200);
frame.setDefaultCloseOperation
(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
JPanel panle = new JPanel();
frame.add(panle);
JLabel lable = new JLabel("Hello World!!!");
panle.add(lable);
}
}
The file name is "JFrame.java" without the quotes.
My issue is that I have two objects that have a "public void paint(Graphics pane)" class, and I want to add them both to a frame. I have the code in place to do so, but only the last die I add actually shows up. Any solutions / additional info you need to see?
The Add code:
public void addDice(Die userDie, Die computerDie) {
gameFrame.add(userDie);
gameFrame.add(computerDie);
}
And yes, the method is called and receives the two dice objects, and the object's class does extend "Component".
gameFrame is a Frame made with
Frame gameFrame = new Frame();
This is an AWT application, not Swing.
Thanks!
Is this a Swing application (JFrame) or an AWT application? Or something else? You may need to change your "Frame's" layout to GridLayout so that it can show both components. You will want to read up on use of the layout managers here