I changed the code again. But now when I run the code, The text box is very small. Only whn I choose either of the left, center or the right alignment, will the text box size change.
Where did I make the mistake.
I have written the below program. When I click on the left, right or the center button, the program should also read the value in the column size textbox and then automatically resize the message textfield. BUt I cannot seem to do it. Any insight will be greatly appreciated.
package workingwithjtextfields;
package workingwithjtextfields;
import java.awt.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.*;
import javax.swing.border.*;
public class WorkingwithJTextFields extends JFrame
{
// private int size = 100;
private JTextField jtfMessage = new JTextField(100);
private JTextField jtfColumn = new JTextField(5);
private JRadioButton jrbLeft,jrbCenter,jrbRight;
public static void main(String[] args) //Main program begins here.
{
JFrame frame = new WorkingwithJTextFields();//Instantiating an object.
frame.setTitle("Exercise 17.11");//Setting the frame title.
frame.setSize(470,110);//Setting the size.
frame.setLocationRelativeTo(null);//Setting the location.
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);// Default closing options.
frame.setVisible(true);//Setting visibility to true.
}//End of main program
public WorkingwithJTextFields()
{
// jtfMessage.setColumns(100);
final JPanel parent = new JPanel();
parent.setLayout(new GridLayout(2,1,3,3));
final JPanel p1 = new JPanel();
p1.setLayout(new FlowLayout(FlowLayout.LEFT,30,0));
p1.add(new JLabel("TextField",SwingConstants.CENTER));
jtfMessage= new JTextField("Type anything",SwingConstants.RIGHT);
jtfMessage.setHorizontalAlignment(SwingConstants.CENTER);
p1.add(jtfMessage);
parent.add(p1);
JPanel jpRadioButtons = new JPanel();
jpRadioButtons.setLayout(new GridLayout(1,3));
jpRadioButtons.add(jrbLeft= new JRadioButton("Left"));
jpRadioButtons.add(jrbCenter = new JRadioButton("Center"));
jpRadioButtons.add(jrbRight = new JRadioButton("Right"));
jpRadioButtons.setBorder(new TitledBorder("Horizontal Border"));
final JPanel p2 = new JPanel();
p2.setLayout(new GridLayout(1,2,1,1));
p2.add(jpRadioButtons);
JPanel p3 = new JPanel();
p3.setLayout(new GridLayout(1,1,1,1));
p3.add(new JLabel("Column Size"));
jtfColumn= new JTextField("60",SwingConstants.RIGHT);
jtfColumn.setHorizontalAlignment(SwingConstants.CENTER);
p3.add(jtfColumn);
Border lineBorder = new LineBorder(Color.LIGHT_GRAY,1);
p3.setBorder(lineBorder);
p2.add(p3);
parent.add(p2);
add(parent);
jrbLeft.addActionListener(
new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
jtfMessage.setHorizontalAlignment(SwingConstants.LEFT);
jrbCenter.setSelected(false);
jrbRight.setSelected(false);
jtfMessage.setColumns(Integer.parseInt(jtfColumn.getText()));
// p1.revalidate();
// p1.repaint();
}
}
);
jrbCenter.addActionListener(
new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
jtfMessage.setHorizontalAlignment(SwingConstants.CENTER);
jrbLeft.setSelected(false);
jrbRight.setSelected(false);
jtfMessage.setColumns(Integer.parseInt(jtfColumn.getText()));
}
}
);
jrbRight.addActionListener(
new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
jtfMessage.setHorizontalAlignment(SwingConstants.RIGHT);
jrbCenter.setSelected(false);
jrbLeft.setSelected(false);
jtfMessage.setColumns(Integer.parseInt(jtfColumn.getText()));
}
}
);
}
}
The main problem is with GridLayout.
GridLayout, by design, gives equal width and height to the components in the column/width based on the available space of the parent container.
Instead, try using something like FlowLayout or GridBagLayout which work with the components preferred size instead
Related
I am currently working on my school project to practice vocabulary, I have a method in my GUI that creates new vocabulary and the name of the list, I wanted to create a button that adds more Panels with input fields just this prototype image.
My idea is that when the user clicks
AddMoreButton it will add one JPanel just like P Panel, then the user can write vocabulary to send it to my database, is it possible to create something that?, I tried looping the P panel but it did not not change, any help would be appreciated.
private JPanel SetUpCreate() {
JPanel createPanel = new JPanel();
nameListInput = new JTextField(INPUT_FIELD_WIDTH);
termInput = new JTextField(INPUT_FIELD_WIDTH);
defintionInput = new JTextField(INPUT_FIELD_WIDTH);
p = new JPanel();
doneCreate = new JButton("Done");
doneCreate.addActionListener(new DoneCreateButtonAction());
addMoreButton = new JButton("Add");
addMoreButton.addActionListener(new AddMorePanelsListener());
p.setBorder(new BevelBorder(BevelBorder.RAISED));
p.add(termInput);
p.add(defintionInput);
JScrollPane pane = new JScrollPane(p);
createPanel.add(nameListInput);
createPanel.add(p);
createPanel.add(pane);
createPanel.add(doneCreate);
return createPanel;
}
private class DoneCreateButtonAction implements ActionListener {
public DoneCreateButtonAction() {
super();
}
public void actionPerformed(ActionEvent e) {
String namelist = nameListInput.getText();
String termglosa = termInput.getText();
String defintionglosa = defintionInput.getText();
try {
if (model.createWordList(namelist) && (model.createGlosa(termglosa, defintionglosa))) {
cl.show(cardPanel, "home");
}
} catch (IOException e1) {
JOptionPane.showMessageDialog(frame, "skapelsen av listan fungerar ej.");
}
}
}
private class AddMoreButtonAction implements ActionListener {
public AddMoreButtonAction() {
super();
}
public void actionPerformed(ActionEvent e) {
}
}
What I understand from your question is that you want to add another panel every time the user clicks the Add button and the panel to add contains fields for entering a word and its definition.
I see JScrollPane appears in the code you posted in your question. I think this is the correct implementation. In the below code, every time the user clicks the Add button I create a panel that contains the fields for a single word definition. This newly created panel is added to an existing panel that uses GridLayout with one column. Hence every time a new word definition panel is added, it is placed directly below the last word panel that was added and this GridLayout panel is placed inside a JScrollPane. Hence every time a word definition panel is added, the GridLayout panel height increases and the JScrollPane adjusts accordingly.
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.WindowConstants;
public class MorPanel implements ActionListener, Runnable {
private static final String ADD = "Add";
private JFrame frame;
private JPanel vocabularyPanel;
#Override
public void run() {
showGui();
}
#Override
public void actionPerformed(ActionEvent actionEvent) {
String actionCommand = actionEvent.getActionCommand();
switch (actionCommand) {
case ADD:
vocabularyPanel.add(createWordPanel());
vocabularyPanel.revalidate();
vocabularyPanel.repaint();
break;
default:
JOptionPane.showMessageDialog(frame,
actionCommand,
"Unhandled",
JOptionPane.ERROR_MESSAGE);
}
}
public JButton createButton(String text) {
JButton button = new JButton(text);
button.addActionListener(this);
return button;
}
public JPanel createButtonsPanel() {
JPanel buttonsPanel = new JPanel();
buttonsPanel.add(createButton(ADD));
return buttonsPanel;
}
private JScrollPane createMainPanel() {
vocabularyPanel = new JPanel(new GridLayout(0, 1));
vocabularyPanel.add(createWordPanel());
JScrollPane scrollPane = new JScrollPane(vocabularyPanel);
return scrollPane;
}
private JPanel createWordPanel() {
JPanel wordPanel = new JPanel();
JLabel wordLabel = new JLabel("Enter Term");
JTextField wordTextField = new JTextField(10);
JLabel definitionLabel = new JLabel("Enter Term Definition");
JTextField definitionTextField = new JTextField(10);
wordPanel.add(wordLabel);
wordPanel.add(wordTextField);
wordPanel.add(definitionLabel);
wordPanel.add(definitionTextField);
return wordPanel;
}
private void showGui() {
frame = new JFrame("Vocabulary");
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.add(createMainPanel(), BorderLayout.CENTER);
frame.add(createButtonsPanel(), BorderLayout.PAGE_END);
frame.setSize(480, 200);
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new MorPanel());
}
}
As your code is not an Minimal Reproducible Example, I cannot provide further assistance than this:
Red part: Your main JPanel with BoxLayout
Green part: another JPanel with your JTextField in it.
Purple part: JScrollPane
Blue parts: custom JPanels with 2 panes in them, one on top for the number, one on the bottom for both JTextFields and icon, so I would say GridBagLayout or BoxLayout + FlowLayout
Orange part: JPanel with GridBagLayout or FlowLayout
Each time you clic on the + icon, you just create a new instance of the custom blue JPanel and that's it.
I am trying to create and Editable JComboBox to allow the user to type the name of the song to purchase. However when I set tunes.setEditable(true); I get an error... any help will be appreciated!
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.JTextArea;
public class JTunes2 extends JFrame implements ItemListener
{
int songNum,songPrice;
int[] songAmount = {2,5,8,1,4,7,12,10,11,3,6,9};
String result;
JComboBox tunes = new JComboBox();
// set as editable
tunes.setEditable(true);
JLabel labelTunes = new JLabel("Song List");
JLabel outputs = new JLabel();
FlowLayout layout = new FlowLayout();
public JTunes2()
{
super("Song Selector");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
panel.setLayout(layout);
// add song names to combo box and register an item listener.
tunes.addItem("Song1");
tunes.addItem("Song2");
tunes.addItem("Song3");
tunes.addItem("Song4");
tunes.addItem("Song5");
tunes.addItem("Song6");
tunes.addItem("Song7");
tunes.addItem("Song8");
tunes.addItem("Song9");
tunes.addItem("Song10");
tunes.addItem("Song11");
tunes.addItem("Song12");
tunes.addItemListener(this);
panel.add(labelTunes);
panel.add(tunes);
panel.add(outputs);
//add panel to the frame
setContentPane(panel);
}
public void itemStateChanged(ItemEvent e)
{
//create source object
Object source = e.getSource();
//check the type size
if(source == tunes)
{
songNum = tunes.getSelectedIndex();
songPrice = songAmount[songNum];
result = "Total Price $" + songPrice;
//Display result
outputs.setText(result);
}
}
public static void main(String[] args)
{
// create class object
JTunes frame = new JTunes();
frame.setSize(250, 180);
frame.setVisible(true);
}
}
Thank you!
Actually, Java requires that you setup JComponents in the constructor. In order for your code to work, you need to call on setEditable(true) in the constructor, which means that you just need to move tunes.setEditable(true); to the constructor.
Tip: always allocate memory for JComponents in the constructor (you want to draw the components as soon as you create the Jframe). You can have a reference to the JComboBox at the class level.
Here is another version of your code:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.JTextArea;
public class JTunes2 extends JFrame implements ItemListener
{
int songNum,songPrice;
int[] songAmount = {2,5,8,1,4,7,12,10,11,3,6,9};
String result;
JComboBox tunes;
JLabel labelTunes = new JLabel("Song List");
JLabel outputs = new JLabel();
FlowLayout layout = new FlowLayout();
public JTunes2()
{
super("Song Selector");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
panel.setLayout(layout);
tunes = new JComboBox();
// set as editable
tunes.setEditable(true);
// add song names to combo box and register an item listener.
tunes.addItem("Song1");
tunes.addItem("Song2");
tunes.addItem("Song3");
tunes.addItem("Song4");
tunes.addItem("Song5");
tunes.addItem("Song6");
tunes.addItem("Song7");
tunes.addItem("Song8");
tunes.addItem("Song9");
tunes.addItem("Song10");
tunes.addItem("Song11");
tunes.addItem("Song12");
tunes.addItemListener(this);
panel.add(labelTunes);
panel.add(tunes);
panel.add(outputs);
//add panel to the frame
setContentPane(panel);
}
public void itemStateChanged(ItemEvent e)
{
//create source object
Object source = e.getSource();
//check the type size
if(source == tunes)
{
songNum = tunes.getSelectedIndex();
songPrice = songAmount[songNum];
result = "Total Price $" + songPrice;
//Display result
outputs.setText(result);
}
}
public static void main(String[] args)
{
// create class object
JTunes2 frame = new JTunes2();
frame.setSize(250, 180);
frame.setVisible(true);
}
}
You added the tunes.setEditable(true) at the class level, instead of at the method level. No statements allowed at the class level!
Here's a fixed version: I renamed JTunes2 to JTunes to fix the compilation errors, and moved the setEditable to the constructor. Also I fixed the indentation - this makes it harder to make this mistake:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.JTextArea;
public class JTunes extends JFrame implements ItemListener
{
int songNum,songPrice;
int[] songAmount = {2,5,8,1,4,7,12,10,11,3,6,9};
String result;
JComboBox tunes = new JComboBox();
JLabel labelTunes = new JLabel("Song List");
JLabel outputs = new JLabel();
FlowLayout layout = new FlowLayout();
public JTunes()
{
super("Song Selector");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
panel.setLayout(layout);
tunes.setEditable(true);
// add song names to combo box and register an item listener.
tunes.addItem("Song1");
tunes.addItem("Song2");
tunes.addItem("Song3");
tunes.addItem("Song4");
tunes.addItem("Song5");
tunes.addItem("Song6");
tunes.addItem("Song7");
tunes.addItem("Song8");
tunes.addItem("Song9");
tunes.addItem("Song10");
tunes.addItem("Song11");
tunes.addItem("Song12");
tunes.addItemListener(this);
panel.add(labelTunes);
panel.add(tunes);
panel.add(outputs);
//add panel to the frame
setContentPane(panel);
}
public void itemStateChanged(ItemEvent e)
{
//create source object
Object source = e.getSource();
//check the type size
if(source == tunes)
{
songNum = tunes.getSelectedIndex();
songPrice = songAmount[songNum];
result = "Total Price $" + songPrice;
//Display result
outputs.setText(result);
}
}
public static void main(String[] args)
{
// create class object
JTunes frame = new JTunes();
frame.setSize(250, 180);
frame.setVisible(true);
}
}
I am writing a small program that converts files, and I wanted to have a box pop up that asks the user to please wait while the program loops through and converts all the relevant files, but I am running into a small problem. The box that pops up should have a JLabel and a JButton, while the user is "waiting" I wanted to display a message that says please wait, and a disabled "OK" JButton, and then when its finished I wanted to set the text of the JLabel to let them know that It successfully converted their files, and give them a count of how many files were converted. (I wrote a method called alert that sets the text of the label and enables the button.) The problem is That while the program is running, the box is empty, the Label and the Button are not visible, when it finishes, label appears with the final text that I want and the button appears enabled. I am not sure exactly what is going on, I tried changing the modifiers of the JLabel and JButton several times but I cant seem to get it to work correctly. Here is the code for the box that pops up, any help is greatly appricated.
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class PleaseWait extends javax.swing.JFrame{
private static final int height = 125;
private static final int width = 350;
final static JLabel converting = new JLabel("Please Wait while I convert your files");
private static JButton OK = new JButton("OK");
public PleaseWait(){
// creates the main window //
JFrame mainWindow = new JFrame();
mainWindow.setTitle("Chill For A Sec");
mainWindow.setSize(width, height);
mainWindow.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
// creates the layouts//
JPanel mainLayout = new JPanel(new BorderLayout());
JPanel textLayout = new JPanel(new FlowLayout());
JPanel buttonLayout = new JPanel(new FlowLayout());
// Sets Text //
converting.setText("Please wait while I convert your files");
// disables button //
OK.setEnabled(false);
// adds to the layouts //
textLayout.add(converting);
buttonLayout.add(OK);
mainLayout.add(textLayout, BorderLayout.CENTER);
mainLayout.add(buttonLayout, BorderLayout.SOUTH);
// adds to the frame //
mainWindow.add(mainLayout);
// sets everything visible //
mainWindow.setVisible(true);
}
public static void alert(){
OK.setEnabled(true);
String total = String.valueOf(Convert.result());
converting.setText("Sucsess! " + total + " files Converted");
}
}
Okay here's the issue. You are extending the JFrame . That means your class IS a JFrame.
When you create the PleaseWait frame you don't do anything to it. This is the empty box you are seeing. You are instead creating a different JFrame in your constructor. Remove your mainWindow and instead just use this. Now all of your components will be added to your PleaseWait object. That should fix your blank box issue.
You need an application to create your frame first. This is a simple example of such application.
import javax.swing.UIManager;
import java.awt.*;
public class Application {
boolean packFrame = false;
//Construct the application
public Application() {
PleaseWait frame = new PleaseWait();
//Validate frames that have preset sizes
//Pack frames that have useful preferred size info, e.g. from their layout
if (packFrame) {
frame.pack();
}
else {
frame.validate();
}
//Center the window
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
Dimension frameSize = frame.getSize();
if (frameSize.height > screenSize.height) {
frameSize.height = screenSize.height;
}
if (frameSize.width > screenSize.width) {
frameSize.width = screenSize.width;
}
frame.setLocation((screenSize.width - frameSize.width) / 2, (screenSize.height - frameSize.height) / 2);
frame.setVisible(true);
frame.convert();
}
//Main method
public static void main(String[] args) {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}
catch(Exception e) {
e.printStackTrace();
}
new Application();
}
}
You have to slightly modify your frame to add controls to the content pane. You can do some work after frame is created, then call alert.
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class PleaseWait extends JFrame {
private static final int height = 125;
private static final int width = 350;
final static JLabel converting = new JLabel();
private static JButton OK = new JButton("OK");
BorderLayout borderLayout1 = new BorderLayout();
JPanel contentPane;
int count;
public PleaseWait(){
contentPane = (JPanel)this.getContentPane();
contentPane.setLayout(borderLayout1);
this.setSize(new Dimension(width, height));
this.setTitle("Chill For A Sec");
this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
// creates the layouts//
JPanel mainLayout = new JPanel(new BorderLayout());
JPanel textLayout = new JPanel(new FlowLayout());
JPanel buttonLayout = new JPanel(new FlowLayout());
// Sets Text //
converting.setText("Please wait while I convert your files");
// disables button //
OK.setEnabled(false);
OK.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
// adds to the layouts //
textLayout.add(converting);
buttonLayout.add(OK);
mainLayout.add(textLayout, BorderLayout.CENTER);
mainLayout.add(buttonLayout, BorderLayout.SOUTH);
// adds to the frame //
contentPane.add(mainLayout);
}
public void convert(){
count = 0;
for (int i = 0; i <10; i++){
System.out.println("Copy "+i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
count++;
}
alert();
}
public void alert(){
OK.setEnabled(true);
// String total = String.valueOf(Convert.result());
converting.setText("Sucsess! " + count + " files Converted");
}
}
Can someone please help me how to set the width of a JTextField at runtime? I want my text field to be resized on runtime. It will ask the user for the length, then the input will change the width of the text field.
if(selectedComponent instanceof javax.swing.JTextField){
javax.swing.JTextField txtField = (javax.swing.JTextField) selectedComponent;
//txtField.setColumns(numInput); //tried this but it doesn't work
//txtField.setPreferredSize(new Dimension(numInput, txtField.getHeight())); //also this
//txtField.setBounds(txtField.getX(), txtField.getY(), numInput, txtField.getHeight());
//and this
txtField.revalidate();
}
I am using null layout for this, since I'm on edit mode.
You simply need to use jTextFieldObject.setColumns(int columnSize). This will let you increase it's size at runtime. The reason why you couldn't do it at your end is the null Layout. That is one of the main reasons why the use of null Layout/Absolute Positioning is discouraged. Here is a small example for trying your hands on :
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class JTextFieldExample
{
private JFrame frame;
private JPanel contentPane;
private JTextField tfield;
private JButton button;
private int size = 10;
private ActionListener action = new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
String input = JOptionPane.showInputDialog(
frame, "Please Enter Columns : "
, String.valueOf(++size));
tfield.setColumns(Integer.parseInt(input));
contentPane.revalidate();
contentPane.repaint();
}
};
private void createAndDisplayGUI()
{
frame = new JFrame("JTextField Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
contentPane = new JPanel();
contentPane.setLayout(new FlowLayout(FlowLayout.LEFT, 5, 5));
tfield = new JTextField();
tfield.setColumns(size);
JButton button = new JButton("INC Size");
button.addActionListener(action);
contentPane.add(tfield);
contentPane.add(button);
frame.getContentPane().add(contentPane);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String... args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new JTextFieldExample().createAndDisplayGUI();
}
});
}
}
For absolute positioning you need to call setSize() on the JTextField in order to attain the result, though you should always keep in mind the reason why this approach is discouraged, as given in the Java Doc's first paragraph:
Although it is possible to do without a layout manager, you should use a layout manager if at all possible. A layout manager makes it easier to adjust to look-and-feel-dependent component appearances, to different font sizes, to a container's changing size, and to different locales. Layout managers also can be reused easily by other containers, as well as other programs.
I got the text field to resize just by using setBounds. Check out the following example:
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.JButton;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Resize extends JFrame{
public JTextField jtf = new JTextField();
public Resize(){
//frame settings
setTitle("Resizable JTextField");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(null);
setSize(new Dimension(600,400));
setResizable(false);
//init and add text field to the frame
add(jtf);
jtf.setBounds(20,50,200,200);
//button to change text field size
JButton b = new JButton("Moar.");
add(b);
b.setBounds(20,20,b.getPreferredSize().width,b.getPreferredSize().height);
b.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent evt){
jtf.setBounds(20,50,jtf.getSize().width+10,jtf.getSize().height); //THIS IS WHERE THE RESIZING HAPPENS
}
});
setVisible(true);
}
public static void main(String[] args){
Resize inst = new Resize();
}
}
"Fun" little run-it-yourself solution:
public static void main(String[] args) {
JFrame frame = new JFrame();
JTextField jTextField = new JTextField("Alice");
JPanel panel = new JPanel();
JButton grow = new JButton("DRINK ME");
JButton shrink = new JButton("EAT ME");
panel.add(jTextField);
panel.add(grow);
panel.add(shrink);
frame.add(panel);
frame.setVisible(true);
frame.pack();
grow.addActionListener(l -> resize(frame, jTextField, 2));
shrink.addActionListener(l -> resize(frame, jTextField, 0.5f));
}
private static void resize(JFrame frame, Component toResize, float factor) {
System.out.println(toResize.getPreferredSize());
toResize.setPreferredSize(new Dimension((int)(toResize.getPreferredSize().width * factor),
(int)(toResize.getPreferredSize().height * factor)));
toResize.setFont(toResize.getFont().deriveFont(toResize.getFont().getSize() * factor));
frame.pack();
}
Attention: Please note that the consumption of too much cake can kill you.
Ok so im working on this game in java called 8 bit chimera. Im working on the main menu right now but when im using the card layout the window wont open for some reason. Here is some code.
import javax.swing.*;
import java.awt.*;
public class MainScreen extends JFrame{
String Title = "MainMenu";
MainMenuComp MMC = new MainMenuComp();
BreedingGround BGR = new BreedingGround();
public MainScreen() {
setTitle("8-bit Chimera "+Title);
setSize(800,600);
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
add(MMC);
add(BGR);
}
public static void main(String[] args){
new MainScreen();
}
}
that was the Main window
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class MainMenuComp extends JPanel implements ActionListener{
BreedingGround BGR = new BreedingGround();
ImageData ID = new ImageData();
Image TitleBg;
Image Title;
CardLayout CL;
JButton Play;
public MainMenuComp() {
setLayout(new GridBagLayout());
GridBagConstraints GBC = new GridBagConstraints();
ImageIcon TitleData = new ImageIcon(ID.TitleSource);
ImageIcon TitleBackGroundData = new ImageIcon(ID.TitleBackGroundSource);
ImageIcon PlayData = new ImageIcon(ID.PlaySource);
TitleBg = TitleBackGroundData.getImage();
Title = TitleData.getImage();
Play = new JButton();
Play.setIcon(PlayData);
add(Play,GBC);
add(BGR,"Breed");
}
public void actionPerformed(ActionEvent AE){
if(AE.getSource() == Play){
CL.show(this, "Breed");
}
}
public void paintComponent(Graphics g){
g.drawImage(TitleBg,0,0,800,600,this);
g.drawImage(Title,250,80,280,140,this);
}
}
this was the card layout
import javax.swing.*;
import java.awt.*;
public class BreedingGround extends JPanel{
ImageData ID = new ImageData();
Image Swamp;
CardLayout CL;
public BreedingGround(){
setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
ImageIcon SwampData = new ImageIcon(ID.SwampSource);
Swamp = SwampData.getImage();
}
public void paintComponent(Graphics g){
g.drawImage(Swamp,0,0,800,600,this);
}
}
and that was what i wanted the CardLayout to open. The problem is that when i try to run it the window wont run and this keeps showing in the compiler.
--------------------Configuration: 8-bit Chimera - JDK version 1.6.0_26 - --------------------
Exception in thread "main" java.lang.IllegalArgumentException: cannot add to layout: constraints must be a GridBagConstraint
at java.awt.GridBagLayout.addLayoutComponent(GridBagLayout.java:685)
at java.awt.Container.addImpl(Container.java:1074)
at java.awt.Container.add(Container.java:927)
at MainMenuComp.<init>(MainMenuComp.java:26)
at MainScreen.<init>(MainScreen.java:7)
at MainScreen.main(MainScreen.java:23)
Process completed.
All i really want to know is what this is saying.
I don't see where you ever set the layout of a container to be CardLayout, and if you don't set the layout to this, you can't magically use it. If you haven't yet gone through the CardLayout tutorial, consider doing so as it's all explained there.
Edit 1
Comment from Alexander Kim:
when i added the cardbagLayout it wont load the image and the button size filled the whole screen. I also took away the grids
You need to nest your JPanels in order to nest layouts. Use a single JPanel as the CardLayout container whose single function it is is to display other JPanels (the "cards"). These other JPanels will use whatever layouts that are necessary to properly display the components that they hold such as your JButton or "grids" (whatever they are). And even these JPanels may hold other JPanels that use other layouts.
Again, please read the layout tutorials as it's all described well there. You will not regret doing this.
Edit 2
Here's a very simple example that uses a CardLayout. The component displayed by the CardLayout using JPanel (called the cardContainer) is changed depending on which item is selected in a combobox.
Here's the CardLayout and the JPanel that uses it:
private CardLayout cardLayout = new CardLayout();
// *** JPanel to hold the "cards" and to use the CardLayout:
private JPanel cardContainer = new JPanel(cardLayout);
And here's how I add a component to the cardlayout-using JPanel:
JPanel redPanel = new JPanel();
//...
String red = "Red Panel";
cardContainer.add(redPanel, red); // add the JPanel to the container with the String
I also add the String to a JComboBox so I can use this combo box later to tell the CardLayout to display this JPanel (redPanel) if the user selects the item "Red" in this same JComboBox:
cardCombo.addItem(red); // also add the String to the JComboBox
Here's the ActionListener in the JComboBox that lets me change the item displayed in the cardlayout using JPanel:
cardCombo.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String item = cardCombo.getSelectedItem().toString();
// *** if combo box changes it tells the CardLayout to
// *** swap views based on the item selected in the combo box:
cardLayout.show(cardContainer, item);
}
});
And here's the whole shebang:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class SimpleCardLayoutDemo {
private CardLayout cardLayout = new CardLayout();
// *** JPanel to hold the "cards" and to use the CardLayout:
private JPanel cardContainer = new JPanel(cardLayout);
private JComboBox cardCombo = new JComboBox();
private JPanel comboPanel = new JPanel();;
public SimpleCardLayoutDemo() {
JPanel greenPanel = new JPanel(new BorderLayout());
greenPanel.setBackground(Color.green);
greenPanel.add(new JScrollPane(new JTextArea(10, 25)), BorderLayout.CENTER);
greenPanel.setBorder(BorderFactory.createEmptyBorder(15, 15, 15, 15));
greenPanel.add(new JButton("Bottom Button"), BorderLayout.PAGE_END);
String green = "Green Panel";
cardContainer.add(greenPanel, green);
cardCombo.addItem(green);
JPanel redPanel = new JPanel();
redPanel.setBackground(Color.red);
redPanel.add(new JButton("Foo"));
redPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
String red = "Red Panel";
cardContainer.add(redPanel, red);
cardCombo.addItem(red);
JPanel bluePanel = new JPanel();
bluePanel.setBackground(Color.blue);
JLabel label = new JLabel("Blue Panel", SwingConstants.CENTER);
label.setForeground(Color.white);
label.setFont(label.getFont().deriveFont(Font.BOLD, 32f));
bluePanel.add(label);
String blue = "Blue Panel";
cardContainer.add(bluePanel, blue);
cardCombo.addItem(blue);
comboPanel.add(cardCombo);
cardCombo.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String item = cardCombo.getSelectedItem().toString();
// *** if combo box changes it tells the CardLayout to
// *** swap views based on the item selected in the combo box:
cardLayout.show(cardContainer, item);
}
});
}
public JPanel getCardContainerPanel() {
return cardContainer;
}
public Component getComboPanel() {
return comboPanel ;
}
private static void createAndShowUI() {
SimpleCardLayoutDemo simplecardDemo = new SimpleCardLayoutDemo();
JFrame frame = new JFrame("Simple CardLayout Demo");
frame.getContentPane().add(simplecardDemo.getCardContainerPanel(), BorderLayout.CENTER);
frame.getContentPane().add(simplecardDemo.getComboPanel(), BorderLayout.PAGE_END);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
// to run Swing in a thread-safe way
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
createAndShowUI();
}
});
}
}
Your problem is with add(BGR,"Breed");. The layout of MainMenuComp is a GridBagLayout, so the constraint must be a GridBagConstraint, not a String (you have "Breed" as the constraint).