I'm new to Java and the entire swing development. I'm working on a Window with three tabs and adding each component to those tabs. I started by adding a textfield to the 3rd tab, but it's taking up the entire tab. I'm sure if I add other components it will make room, but isn't there a way to make it so it doesn't initially take up the entire Tabbed Pane?
package literature.windows;
import java.awt.*;
import javax.swing.*;
public class MainWindow extends JFrame {
JPanel storiesPanel = new JPanel();
JPanel plotPanel = new JPanel();
JPanel charactersPanel = new JPanel();
JTextField addCharacterTextField = new JTextField("Enter Character's Name", 25);
public MainWindow() {
setSize(800, 600);
JTabbedPane tabs = new JTabbedPane();
tabs.addTab("Stories", storiesPanel);
tabs.addTab("Plot", plotPanel);
tabs.addTab("Characters", charactersPanel);
add(tabs);
tabs.setTabComponentAt(2, addCharacterTextField);
setVisible(true);
}
}
You are currently setting the entire tab component for that tab. Instead you need to add the JTextField to the container/panel for that tab. Replace
tabs.setTabComponentAt(2, addCharacterTextField);
with
charactersPanel.add(addCharacterTextField);
Related
I am trying to make a minesweeper that has a different space for a smiley icon that we can click and the buttons which we have to click to play.
public final class testFrame extends JFrame implements MouseListener, ActionListener {
private JFrame screen = null;
private JPanel composite = new JPanel();
public testFrame() {
screen = new JFrame();
screen.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
screen.setVisible(true);
screen.setResizable(true);
composite.setLayout(new BorderLayout());
//this button is not showing also
JButton button = new JButton("Text goes here");
composite.add(button);
Container cp = screen.getContentPane(); // JFrame's content-pane
cp.setLayout(new GridLayout(5, 5, 2, 2)); // in 10x10 GridLayout
//codes to add buttons
}
So here I am trying to add the container cp to the screen. But it opened
two screen
Sorry if this seems like minor things but I am really new to this java GUI so please help me.
EDIT:
I removed the extends JFrame and used the screen instead. It kinda works but I can't seem to put the container cp to a panel. The requirement is that I have to use container cp. So I cannot change. Thank you
public final class TestFrame implements MouseListener, ActionListener {
private JFrame screen = null;
private JPanel composite = new JPanel();
private JPanel topPanel = new JPanel();
public TestFrame() {
screen = new JFrame("TestFrame");
screen.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
screen.setVisible(true);
topPanel.setLayout(new BorderLayout());
//composite.setLayout(new BorderLayout());
//button in topPanel
JButton button = new JButton("Text goes here");
topPanel.add(button, BorderLayout.PAGE_START);
//Content Pane
Container cp = screen.getContentPane();// JFrame's content-pane
cp.setLayout(new GridLayout(5, 5, 2, 2)); // in 10x10 GridLayout
//composite.add(cp, BorderLayout.CENTER);
screen.add(topPanel);
// screen.add(composite);
}
Now it looks like
this
There are a few things.
You are extending JFrame as well as using it as an attribute of the same class so you can ether use this instead of screen or you remove the extends JFrame as it is redundant and not needed
To answer your question. A JFrame contains a Panel called ContentPane this pane is were you add you panels to (you already did the layout thing right). So the solution is:
cp.add(composite);
You've got too many JFrames, the testFrame class which extends JFrame (and which should be re-named TestFrame to comply with Java naming conventions) and the screen variable. Use only one.
You can and should nest JPanels to achieve your desired result. For instance if you want a grid as well as some control buttons, create a JPanel, give it a BorderLayout, put your grid JPanel in the BorderLayout.CENTER postion and a JPanel with control JButtons in a different position, say BorderLayout.PAGE_START
I am adding components in JPanel which is set as FlowLayout, they are not moving on next line even there is no space in left in that line.
Here is the screenshot of the problem
import javax.swing.*;
import java.awt.*;
import javax.swing.border.BevelBorder;
import javax.swing.border.TitledBorder;
public class GUI extends JFrame
{
private JLabel jlfname;
private JPanel p1;
private JTextField t1;
private JLabel jllname;
private JTextField t2;
private JLabel jltitle;
private JTextField t3;
GUI()
{
jlfname=new JLabel("First Name : ");
p1=new JPanel();
TitledBorder titled = new TitledBorder("Name");
p1.setBorder(titled);
t1=new JTextField(10);
jllname=new JLabel("Last Name : ");
t2=new JTextField(10);
jltitle=new JLabel("Title : ");
t3=new JTextField(10);
//Add in Pannel
p1.setLayout(new FlowLayout());
p1.add(jlfname);
p1.add(t1);
p1.add(jllname);
p1.add(t2);
p1.add(jltitle);
p1.add(t3);
//Add in Frame
add(p1);
setSize(550,500);
setTitle("JFrame Tutorial");
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new FlowLayout(FlowLayout.LEFT));
setResizable(false);
setVisible(true);
}
public static void main(String [] args)
{
new GUI();
}
}
I have also tried to set width of the panel but it doesn't work!
FlowLayout is designed to calculate its preferred size based on all components being displayed on a single line. The FlowLayout also respects the preferred size of components.
setLayout(new FlowLayout(FlowLayout.LEFT));
You are overriding the default layout manager of the frame, so now the frame will respect the preferred size of the panel added to the frame, which means all the components will be displayed on a single line.
Get rid of that statement.
Now the components will be able to wrap in the space available because by default the panel will be added to the BorderLayout.CENTER which takes up all the space available in the frame.
However the above solution will only work when components are added to the CENTER of the BorderLayout. Normally you should not be using setSize() but instead use pack() to all a frame to display at its preferred size.
For a more flexible layout that will calculate a proper preferred size of a panel check out the Wrap Layout. This class extends FlowLayout to calculate the preferred size.
I am working with Swing, trying to learn how to use it. I am doing an excercise in my book where I am supposed to make buttons (JButtons) like the ones a dvd-player has. I am adding no funcionality to the buttons at this point. The program worked just fine when I first ran it. Then I thought that I would expand it by making a second panel (JPanel) with the same buttons. When I run my code however, I just get one set of buttons (not two areas with two sets of buttons).
Have I misunderstood the concept of Panels? I have understood a Panel to be an area (a container) in my frame where I can display different output, and that I can have several panels i one frame.
Here is my code:
import javax.swing.*;
public class Oppgave91 extends JFrame
{
public Oppgave91()
{
super ("We make buttons");
setDefaultCloseOperation(EXIT_ON_CLOSE);
JButton play = new JButton("Play");
JButton stopeject = new JButton("Stop/Eject");
JButton rewind = new JButton("Rewind");
JButton fastforward = new JButton("FastForward");
JButton pause = new JButton("Pause");
JPanel panel = new JPanel();
panel.add(play);
panel.add(stopeject);
panel.add(rewind);
panel.add(fastforward);
panel.add(pause);
JPanel panel2 = new JPanel();
panel2.add(play);
panel2.add(stopeject);
panel2.add(rewind);
panel2.add(fastforward);
panel2.add(pause);
add(panel);
add(panel2);
setVisible(true);
}
public static void main(String[] args)
{
Oppgave91 showbuttons = new Oppgave91();
showbuttons.pack();
}
}
A component can have only 1 parent. See the last line of my code snippet for how it should be done
JPanel panel = new JPanel();
panel.add(play);
panel.add(stopeject);
panel.add(rewind);
panel.add(fastforward);
panel.add(pause);
//right now panel is the parent component of play, stop, eject
JPanel panel2 = new JPanel();
panel2.add(play); //play is now owned by panel2, not panel
panel2.add(stopeject); //stopeject is now owned by panel2, not panel
panel2.add(new JButton("Rewind")); // this is how you should do this
I have this incredibly easy task of wanting a nice centered JPanel inside another JPanel. The parent is set to 900, 550, and the child should be approximately 200,400 or so.
To do this, I thought giving the parent a BorderLayout and then setting the setPreferredSize(200, 400) of the child. This child would be in the CENTER. Two empty JPanels would be on the EAST and WEST. Of course this did not work. Giving the two sidepanels a setPreferredSize() of course DID work. Problem with this is that narrowing the Frame causes the center pane to go away.
Here's some sample code that should give show the issue:
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Component;
import java.awt.Dimension;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class Temporary {
public static Temporary myObj = null;
private JFrame mainFrame;
public void go(){
mainFrame = new JFrame("Swing");
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainFrame.setPreferredSize(new Dimension(900,550));
JPanel mainCards = new JPanel(new CardLayout());
mainCards.add(loginLayer(), "Login");
mainFrame.setContentPane(mainCards);
mainFrame.pack();
mainFrame.setLocationRelativeTo(null);
mainFrame.setVisible(true);
}
public JPanel loginLayer(){
JPanel masterPane = new JPanel(new BorderLayout());
JPanel centerPane = new JPanel();
centerPane.setLayout(new BoxLayout(centerPane, BoxLayout.Y_AXIS));
centerPane.setPreferredSize(new Dimension(100,200));
JLabel label = new JLabel("Swing is overly");
label.setAlignmentX(Component.CENTER_ALIGNMENT);
centerPane.add(label);
JButton button = new JButton("complicated");
button.setAlignmentX(Component.CENTER_ALIGNMENT);
centerPane.add(button);
JTextField textField = new JTextField(10);
centerPane.add(textField);
JPanel filler = new JPanel();
JPanel filler2 = new JPanel();
masterPane.add(filler, BorderLayout.WEST);
masterPane.add(centerPane, BorderLayout.CENTER);
masterPane.add(filler2, BorderLayout.EAST);
return masterPane;
}
public static void main(String[] args){
myObj = new Temporary();
myObj.go();
}
}
BorderLayout will, by it's nature, give as much of the available space as it can to the CENTER component. This is how it's designed.
If you want the component to be centered within the parent container, BUT maintain it's preferred size, you should consider using a GridBagLayout instead. Without any additional constraints, this should achieve the result you're after
For example...
public JPanel loginLayer(){
JPanel masterPane = new JPanel(new GridBagLayout);
JPanel centerPane = new JPanel();
centerPane.setLayout(new BoxLayout(centerPane, BoxLayout.Y_AXIS));
JLabel label = new JLabel("Swing is overly");
label.setAlignmentX(Component.CENTER_ALIGNMENT);
centerPane.add(label);
JButton button = new JButton("complicated");
button.setAlignmentX(Component.CENTER_ALIGNMENT);
centerPane.add(button);
JTextField textField = new JTextField(10);
centerPane.add(textField);
masterPane.add(centerPane);
// Add additional borders to providing padding around the center pane
// as you need
return masterPane;
}
I would also avoid actively setting the preferred size of component in this way, as it's possible that the components you're adding to it will exceed your expectations, instead, make use of things like EmptyBorder (for example) to add additional white space arouond the component and it's contents
In Java Swing, you generally want to avoid creating a bunch of statically positioned items with preferred sizes and absolute positions, because things get weird with resizing (as you've noticed). Instead you want to rely on the fluid LayoutManagers. There is an excellent tutorial here. Or, if you want to supply a mock-up of some sort to show the actual UI you are trying to create, I could provide some more feedback.
Trying to change the look of a JOptionPane while its open, depending on which radiobutton the user clicks. What am I doing wrong? It works perfect if I for example add a button and move a JLabel from side to side of the window.
import java.awt.BorderLayout;
import java.awt.event.*;
import javax.swing.*;
import static javax.swing.JOptionPane.*;
public class ChangePanel extends JFrame{
private JButton click = new JButton("CLICK ME!");
ChangePanel(){
add(click, BorderLayout.SOUTH);
click.addActionListener(new ButtonListen());
setVisible(true);
setSize(300,100);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLocationRelativeTo(null);
}
public class ButtonListen implements ActionListener{
public void actionPerformed(ActionEvent e){
PopUpPanel pop = new PopUpPanel();
showConfirmDialog(ChangePanel.this, pop, "Changeable", OK_CANCEL_OPTION);
}
}
//Send this as Parameter to the ConfirmDialog
public class PopUpPanel extends JPanel implements ActionListener{
JRadioButton jewelry = new JRadioButton("Jewelry");
JRadioButton shares = new JRadioButton("Shares");
JRadioButton machine = new JRadioButton("Machine");
PopUpPanel(){
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
ButtonGroup bg = new ButtonGroup();
JPanel north = new JPanel();
bg.add(jewelry);
jewelry.addActionListener(this);
bg.add(shares);
shares.addActionListener(this);
bg.add(machine);
machine.addActionListener(this);
north.add(jewelry);
north.add(shares);
north.add(machine);
add(north);
}
//Listener for RadioButtons
public void actionPerformed(ActionEvent e){
JTextField info1Txt = new JTextField(12);
JTextField info2Txt = new JTextField(12);
JTextField info3Txt = new JTextField(3);;
JRadioButton b = (JRadioButton)e.getSource();
if(b.getText().equals("Jewelry")){
//Dummy test text
System.out.println("Jewelry");
JPanel info1 = new JPanel();
info1.add(new JLabel("info1:"));
info1.add(info1Txt);
add(info1);
JPanel info2 = new JPanel();
info2.add(new JLabel("info2:"));
info2.add(info2Txt);
add(info2);
JPanel info3 = new JPanel();
info3.add(new JLabel("info3:"));
info3.add(info3Txt);
add(info3);
validate();
repaint();
}else if(b.getText().equals("Shares")){
//Dummy test text
System.out.println("Shares");
}else
//Dummy test text
System.out.println("Machine");
}
}
public static void main(String[] args){
new ChangePanel();
}
}
As you are working with BoxLayout, you should provide size hints to the PopUpPanel panel, which you haven't given.
When a BoxLayout lays out components from top to bottom, it tries to size each component at the component's preferred height. If the vertical space of the layout does not match the sum of the preferred heights, then BoxLayout tries to resize the components to fill the space. The components either grow or shrink to fill the space, with BoxLayout honoring the minimum and maximum sizes of each of the components.
check out the official tutorial page discussion: BoxLayout Feature
Call revalidate() and repaint() on the container after removing or adding components to it. So if you change the following lines:
validate();
repaint();
to:
revalidate();
repaint();
The content should appear. Though, it will not fit the original size of the JOptionPane. You can override PopUpPanel.getPreferredSize() to return desired size so that JOptionPane is packed properly, ie:
#Override
public Dimension getPreferredSize() {
return new Dimension(300, 300);
}
You can also use JDialog instead of JOptionPane.
Also, consider using CardLayout instead of swapping components manually. Check How to Use CardLayout for examples.
Why not just use setPreferredSize(new Dimension(300, 300)) in PopUpPanel constructor? Works fine for me. Good eye on revalidate and repaint.