I'm trying to get a BasicArrowButton component to resize and can't get it to work for the life of me. The following code is a much simpler version of the problem, but still demonstrates what I'm trying to do. The button is in a JPanel with the panel's layout set to FlowLayout. It needs to resize while still remaining in the panel with the same layout. Thanks in advance, and sorry for bad formatting:
Main class:
package PackageMain;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.WindowConstants;
public class Main {
public static JFrame frame = new JFrame("Window");
public static PanelOne p1;
public static PanelTwo p2;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setBounds(100, 100, 800, 600);
p1 = new PanelOne();
frame.setVisible(true);
} catch(Exception e){
}
}
});
}
}
Second Class:
package PackageMain;
import java.awt.Dimension;
import java.awt.FlowLayout;
import javax.swing.JPanel;
import javax.swing.plaf.basic.BasicArrowButton;
public class PanelOne{
public PanelOne(){
FlowLayout fl = new FlowLayout();
BasicArrowButton b1 = new BasicArrowButton(BasicArrowButton.WEST);
JPanel p1 = new JPanel();
p1.add(b1);
p1.setLayout(fl);
b1.setPreferredSize(new Dimension(100, 100)); //DOESN'T WORK!
Main.frame.add(p1);
}
}
The problem is that the class BasicArrowButton overrides the method getPreferredSize(). So you either need to use layout, which does not honor this method, or provide your own implementation for this method.
First proposal:
import java.awt.Dimension;
import java.awt.GridLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
import javax.swing.plaf.basic.BasicArrowButton;
public class BasicArrowButtonTest {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frm = new JFrame("Test arrow button");
JPanel p = new JPanel(new GridLayout(1, 1));
p.setPreferredSize(new Dimension(100, 100));
p.add(new BasicArrowButton(BasicArrowButton.WEST));
frm.add(p);
frm.pack();
frm.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frm.setLocationRelativeTo(null);
frm.setVisible(true);
}
});
}
}
Second proposal:
package org.swingsamples.label;
import java.awt.Dimension;
import java.awt.FlowLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
import javax.swing.plaf.basic.BasicArrowButton;
public class BasicArrowButtonTest {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frm = new JFrame("Test arrow button");
JPanel p = new JPanel(new FlowLayout());
BasicArrowButton btn = new BasicArrowButton(BasicArrowButton.WEST) {
#Override
public Dimension getPreferredSize() {
return new Dimension(100, 100);
}
};
p.add(btn);
frm.add(p);
frm.pack();
frm.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frm.setLocationRelativeTo(null);
frm.setVisible(true);
}
});
}
}
Related
I am making a program that has multiple sub-programs but when I am trying to open a new frame, it doesn't do anything.
The program that calls the frame:
import javax.swing.*;
import java.awt.*;
public class Main {
public static void main(String[] args) {
JFrame frame = new JFrame("Options");
JButton notepad = new JButton("Notepad");
JButton todo = new JButton("To-Do List");
NoteListe noteListener = new NoteListe();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500,500);
frame.setLayout(new GridLayout(1,2));
frame.add(notepad);
frame.add(todo);
notepad.addActionListener(noteListener);
}
}
The action listener for the notepad button:
import java.awt.event.*;
public class NoteListe implements ActionListener{
public void actionPerformed(ActionEvent e){
new MainNote();
}
}
The notepad:
import javax.swing.*;
import java.awt.*;
public class MainNote {
public static void main(String[] args) {
JFrame frame = new JFrame("Text Editor");
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500,500);
frame.setLayout(new GridLayout(2,1));
}
}
I really think you need to take a closer look at:
Providing Constructors for Your Classes
Defining Methods
Passing Information to a Method or a Constructor
These are really fundamental concepts and you should have firm grasp of them before you venture into the wild and unforgiving world of GUI development.
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.border.EmptyBorder;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.add(new MenuPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class MenuPane extends JPanel {
public MenuPane() {
setLayout(new GridBagLayout());
setBorder(new EmptyBorder(32, 32, 32, 32));
JButton notepad = new JButton("Notepad");
JButton todo = new JButton("To-Do List");
GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.BOTH;
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.insets = new Insets(8, 8, 8, 8);
add(notepad, gbc);
add(todo, gbc);
notepad.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
MainNote note = MainNote.show(MenuPane.this);
note.setText("This is where your text goes");
}
});
}
}
public static class MainNote extends JPanel {
private JTextArea ta;
public MainNote() {
setLayout(new BorderLayout());
ta = new JTextArea(20, 40);
add(new JScrollPane(ta));
}
public void setText(String text) {
ta.setText(text);
}
public String getText() {
return ta.getText();
}
public static MainNote show(Component parent) {
MainNote mainNote = new MainNote();
JFrame frame = new JFrame("Text Editor");
frame.add(mainNote);
frame.pack();
frame.setLocationRelativeTo(parent);
frame.setVisible(true);
return mainNote;
}
}
}
Note: I've used a static method (show) to simplify the construction of another window. This is simply a delegation workflow, as I'm delegating the responsibility for creating the window to the method, but I'm still getting back an instance of the MainNote.
Because MainNote is simply a JPanel, it can be added to what ever container I want. Because I've "encapsulated" the functionality into the class itself, it makes it much easier to manage.
list is to accept input from Action1 this works, however, whenever a new element is added to the list, the list's position moves back to the default top-middle position.
This also occurs when the frame is resized, so as a temporary fix I the line frame.setResizable(false) but I do not want that to be permanent.
How would I fix both of these issues?
import static java.lang.String.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.event.ActionListener;
public class lists
{
static String newUrl;
static DefaultListModel<String> model = new DefaultListModel<String>();
static int listXCoord = 650;
static int listYCoord = 10;
public static void createGUI()
{
JFrame frame = new JFrame();
frame.setVisible(true);
frame.setSize(800,600);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
JPanel panel = new JPanel();
frame.add(panel);
JButton addurl = new JButton("Add URL");
panel.add(addurl);
addurl.addActionListener(new Action1());
JButton remurl = new JButton("Remove URL");
panel.add(remurl);
//model.addElement("one");
//model.addElement("two");
//model.addElement("three");
JList list = new JList<String>(model);
list.setCellRenderer(new DefaultListCellRenderer());
list.setVisible(true);
list.setLocation(listXCoord, listYCoord);
list.setBackground(new Color(186, 203, 250));
//list.setLocation(650, 10);
panel.add(list);
list.setSize(130, 540);
}
static class Action1 implements ActionListener
{
public void actionPerformed (ActionEvent e)
{
newUrl = JOptionPane.showInputDialog("Enter the URL to be Launched");
model.addElement(newUrl);
}
}
public static void main(String[] args)
{
createGUI();
}
}
Basically, you're fighting the layout manager (Flowlayout) and losing. When you add a new element to the JList, the container hierarchy is been revalidated which is causing the layout managers to re-layout the contents of their containers
The basic solution would be to use a different layout, but, JFrame uses a BorderLayout, so instead of adding the JList to the JPanel, you could simply add it to the EAST position of the frame instead
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.DefaultListCellRenderer;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Lists {
static String newUrl;
static DefaultListModel<String> model = new DefaultListModel<String>();
static int listXCoord = 650;
static int listYCoord = 10;
public static void createGUI() {
JFrame frame = new JFrame();
frame.setSize(800, 600);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
frame.add(panel);
JButton addurl = new JButton("Add URL");
panel.add(addurl);
addurl.addActionListener(new Action1());
JButton remurl = new JButton("Remove URL");
panel.add(remurl);
//model.addElement("one");
//model.addElement("two");
//model.addElement("three");
JList list = new JList<String>(model);
list.setCellRenderer(new DefaultListCellRenderer());
list.setVisible(true);
list.setLocation(listXCoord, listYCoord);
list.setBackground(new Color(186, 203, 250));
//list.setLocation(650, 10);
frame.add(new JScrollPane(list), BorderLayout.EAST);
frame.setVisible(true);
}
static class Action1 implements ActionListener {
public void actionPerformed(ActionEvent e) {
newUrl = JOptionPane.showInputDialog("Enter the URL to be Launched");
model.addElement(newUrl);
}
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
createGUI();
}
});
}
}
See Laying Out Components Within a Container, How to Use BorderLayout and How to use FlowLayout for more details.
You should also be calling setVisible last, after all the components have been added to the frame, this reduces the possibilities that some of your components won't be displayed when you think they should be.
JList will also benefit from been contained within a JScrollPane. See How to Use Lists and How to Use Scroll Panes for more details
JTabbedPane - tab border is being shown even after using BasicTabbedPaneUI. Please let me know how can I change such that no border is shown between the tabs? Is there any method to remove the border completely ?
Please Send me the code snippet. Thanks in advance.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.plaf.basic.BasicTabbedPaneUI;
public class TabbedPaneTest implements Runnable {
#Override
public void run() {
final JTabbedPane pane = new JTabbedPane();
pane.addTab("A", createTab(Color.RED));
pane.addTab("B", createTab(Color.YELLOW));
pane.addTab("C", createTab(Color.BLUE));
pane.setUI(new BasicTabbedPaneUI() {
#Override
protected void paintContentBorder(Graphics g, int tabPlacement, int selectedIndex) {
}
});
pane.setBackground(Color.WHITE);
pane.addChangeListener(new ChangeListener() {
#Override
public void stateChanged(ChangeEvent arg0) {
pane.setForegroundAt(pane.getSelectedIndex(), Color.GREEN);
}
});
final JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(pane);
frame.pack();
//frame.setSize(500, 200);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private JPanel createTab(Color color) {
JPanel p = new JPanel(new BorderLayout()) {
private static final long serialVersionUID = 1L;
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 300);
}
};
p.setBorder(BorderFactory.createLineBorder(color, 2));
p.setBackground(Color.WHITE);
return p;
}
public static void main(String[] args) throws Exception {
SwingUtilities.invokeLater(new TabbedPaneTest());
}
}
// Remove the white line under a tab button
Insets insets = UIManager.getInsets("TabbedPane.contentBorderInsets");
insets.top = -1;
UIManager.put("TabbedPane.contentBorderInsets", insets);
I'm trying to put my jpanel in the middle of the frame... so when the user try to change the size of the window frame, it remain in the middle...
something like this:
so if i change size it have to remain in the middle:
i Tried to change the layout of my contentPane with the BorderLayout and put my jpanel in the center position... but when i change size of my frame the panel go in the top left corner.
In my windows builder the situation is this:
my jpanel have to work exactly how works the redbox. i tried everything but the result is everytime the same:
this is my code:
package StudApp;
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.util.ArrayList;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JMenuBar;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JTextPane;
import javax.swing.JLabel;
import java.awt.Font;
import javax.swing.SwingConstants;
import java.awt.Color;
import javax.swing.JTextArea;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class StudApp {
private JFrame frame;
private JPanel homeFirstRun;
private ArrayList<Corso> corsi = new ArrayList<Corso>();
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
new StudApp();
}
});
}
/**
* Create the frame.
*/
public StudApp() {
frame = new JFrame("Student Note");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setBounds(100, 100, 450, 300);
JMenuBar menuBar = new JMenuBar();
frame.setJMenuBar(menuBar);
JMenu menuHelp = new JMenu("Help");
menuBar.add(menuHelp);
JMenuItem menuIstrStud = new JMenuItem("Intructions Student Note");
menuIstrStud.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
frame.remove(homeFirstRun);
frame.revalidate();
frame.repaint();
homeFirstRun = null;
}
});
menuHelp.add(menuIstrStud);
homeFirstRun = new JPanel();
homeFirstRun.setBorder(new EmptyBorder(5, 5, 5, 5));
homeFirstRun.setLayout(null);
frame.getContentPane().add(homeFirstRun);
JLabel welcomeMessage = new JLabel("Welcome to Student Note");
welcomeMessage.setBounds(5, 5, 424, 18);
welcomeMessage.setForeground(Color.DARK_GRAY);
welcomeMessage.setHorizontalAlignment(SwingConstants.CENTER);
welcomeMessage.setFont(new Font("Verdana", Font.BOLD, 14));
homeFirstRun.add(welcomeMessage);
JTextArea welcomeTextArea = new JTextArea();
welcomeTextArea.setFont(new Font("Verdana", Font.PLAIN, 13));
welcomeTextArea.setText(" I think it's your first time here.\n\n"
+ " So the first step is to create a new course to\n insert your grades.\n\n"
+ " If you want my advice, read how this program\n works in the help section (it is very simple),\n "
+ "just 2 minutes ... believe me");
welcomeTextArea.setEditable(false);
welcomeTextArea.setBounds(27, 34, 381, 184);
homeFirstRun.add(welcomeTextArea);
frame.setVisible(true);
}
}
There are several ways to do this, but one of the easiest is to give the contentPane a GridBagLayout, and then add your JPanel of interest with no GridBagConstraints. If the JPanel of interest is the only thing added to this container, this will then place that JPanel into a central position.
e.g.,
import java.awt.*;
import javax.swing.*;
public class CentralPanel {
private static void createAndShowGui() {
JFrame frame = new JFrame("CentralPanel");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(new MyContentPane());
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
class MyContentPane extends JPanel {
private static final int PREF_W = 700;
private static final int PREF_H = 550;
public MyContentPane() {
setLayout(new GridBagLayout());
add(new JPanelOfInterest());
}
#Override
public Dimension getPreferredSize() {
return new Dimension(PREF_W, PREF_H);
}
}
class JPanelOfInterest extends JPanel {
private static final int PREF_W = 400;
private static final int PREF_H = PREF_W;
public JPanelOfInterest() {
setBorder(BorderFactory.createTitledBorder("JPanel of Interest"));
}
#Override
public Dimension getPreferredSize() {
return new Dimension(PREF_W, PREF_H);
}
}
I have a problem with my JLayeredPane, I am probably doing something incredibly simple but I cannot wrap my head around it. The problem i have is that all the components are merged together and have not order. Could you please rectify this as I have no idea. The order I am trying to do is have a layout like this
output
label1 (behind)
input (in Front)
import java.awt.BorderLayout;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.IOException;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class window extends JFrame implements KeyListener {
/**
*
*/
private static final long serialVersionUID = 7092006413113558324L;
private static int NewSize;
public static String MainInput;
public static JLabel label1 = new JLabel();
public static JTextField input = new JTextField(10);
public static JTextArea output = new JTextArea(main.Winx, NewSize);
public window() {
super("Satine. /InDev-01/");
JLabel label1;
NewSize = main.Winy - 20;
setLayout(new BorderLayout());
output.setToolTipText("");
add(input, BorderLayout.PAGE_END);
add(output, BorderLayout.CENTER);
input.addKeyListener(this);
input.requestFocus();
ImageIcon icon = new ImageIcon("C:\\Users\\" + System.getProperty("user.name") + "\\AppData\\Roaming\\.Satine\\img\\textbox.png", "This is the desc");
label1 = new JLabel(icon);
add(label1, BorderLayout.PAGE_END);
}
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if (key == KeyEvent.VK_ENTER) {
try {
MainMenu.start();
} catch (IOException e1) {
System.out.print(e1.getCause());
}
}
}
#Override
public void keyReleased(KeyEvent e) {
}
#Override
public void keyTyped(KeyEvent e) {
}
}
And the main class.
import java.awt.Container;
import java.io.IOException;
import javax.swing.JFrame;
import javax.swing.JLayeredPane;
public class main {
public static int Winx, Winy;
private static JLayeredPane lpane = new JLayeredPane();
public static void main(String[] args) throws IOException{
Winx = window.WIDTH;
Winy = window.HEIGHT;
window Mth= new window();
Mth.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Mth.setSize(1280,720);
Mth.setVisible(true);
lpane.add(window.label1);
lpane.add(window.input);
lpane.add(window.output);
lpane.setLayer(window.label1, 2, -1);
lpane.setLayer(window.input, 1, 0);
lpane.setLayer(window.output, 3, 0);
Mth.pack();
}
}
Thank you for your time and I don't expect the code to be written for me, all I want is tips on where I am going wrong.
I recommend that you not use JLayeredPane as the overall layout of your GUI. Use BoxLayout or BorderLayout, and then use the JLayeredPane only where you need layering. Also, when adding components to the JLayeredPane, use the add method that takes a Component and an Integer. Don't call add(...) and then setLayer(...).
Edit: it's ok to use setLayer(...) as you're doing. I've never used this before, but per the API, it's one way to set the layer.
e.g.,
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagLayout;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;
public class LayeredPaneFun extends JPanel {
public static final String IMAGE_PATH = "http://duke.kenai.com/" +
"misc/Bullfight.jpg";
public LayeredPaneFun() {
try {
BufferedImage img = ImageIO.read(new URL(IMAGE_PATH));
ImageIcon icon = new ImageIcon(img);
JLabel backgrndLabel = new JLabel(icon);
backgrndLabel.setSize(backgrndLabel.getPreferredSize());
JPanel forgroundPanel = new JPanel(new GridBagLayout());
forgroundPanel.setOpaque(false);
JLabel fooLabel = new JLabel("Foo");
fooLabel.setFont(fooLabel.getFont().deriveFont(Font.BOLD, 32));
fooLabel.setForeground(Color.cyan);
forgroundPanel.add(fooLabel);
forgroundPanel.add(Box.createRigidArea(new Dimension(50, 50)));
forgroundPanel.add(new JButton("bar"));
forgroundPanel.add(Box.createRigidArea(new Dimension(50, 50)));
forgroundPanel.add(new JTextField(10));
forgroundPanel.setSize(backgrndLabel.getPreferredSize());
JLayeredPane layeredPane = new JLayeredPane();
layeredPane.setPreferredSize(backgrndLabel.getPreferredSize());
layeredPane.add(backgrndLabel, JLayeredPane.DEFAULT_LAYER);
layeredPane.add(forgroundPanel, JLayeredPane.PALETTE_LAYER);
setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
add(new JScrollPane(new JTextArea("Output", 10, 40)));
add(layeredPane);
} catch (MalformedURLException e) {
e.printStackTrace();
System.exit(1);
} catch (IOException e) {
e.printStackTrace();
System.exit(1);
}
}
private static void createAndShowGui() {
JFrame frame = new JFrame("LayeredPaneFun");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new LayeredPaneFun());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}