Java tabs in GUI - java

I am hoping someone can spoon feed me this solution. It is part of my major lab for the class, and it really isn't giving me too much since I just don understand how to make a GUI with tabs. I can make a regular program with some sort of GUI, but I've been searching and reading and can't put 2 and 2 because of the whole class part and declaring the private variables. So what I am asking is if someone can make me a main GUI with 5 tabs and put my code into 1 tab so I can learn and put the rest of my codes into the other 4 tabs. So I hope you don't think I want you to give me code when I have the code, I just don't really get the tabs, and we haven't gone over it in class. Here is the code with its own gui, I hope what I type makes sense. I learn code by seeing, and this will help me a bunch.
package landscape;
import javax.swing.*;
import java.awt.Component;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.event.*;
import java.text.DecimalFormat;
public class Landscape extends JFrame {
private JFrame mainFrame;
private JButton calculateButton;
private JButton exitButton;
private JTextField lengthField;
private JLabel lengthLabel;
private JTextField widthField;
private JLabel widthLabel;
private JTextField depthField;
private JLabel depthLabel;
private JTextField volumeField;
private JLabel volumeLabel;
private JRadioButton builtIn;
private JRadioButton above;
private JTabbedPane panel;
public Landscape()
{
JTabbedPane tabs=new JTabbedPane();
tabs.addTab("Pool", panel);//add a tab for the panel with the title "title"
//you can add more tabs in the same fashion - obviously you can change the title
//tabs.addTab("another tab", comp);//where comp is a Component that will occupy the tab
mainFrame.setContentPane(tabs);//the JFrame will now display the tabbed pane
mainFrame.setSize(265,200);
mainFrame.setLocationRelativeTo(null);
mainFrame.setVisible(true);
mainFrame.setResizable(false);
JPanel panel = new JPanel();//FlowLayout is default
//Pool
panel.setOpaque(false);//this tells the panel not to draw its background; looks nicer under LAFs where the background inside a tab is different from that of JPanel
panel.add(builtIn);
panel.add(above);
panel.add(lengthLabel);
panel.add(lengthField);
panel.add(widthLabel);
panel.add(widthField);
panel.add(depthLabel);
panel.add(depthField);
panel.add(volumeLabel);
panel.add(volumeField);
panel.add(calculateButton);
panel.add(exitButton);
//creating components
calculateButton = new JButton ("Calculate");
exitButton = new JButton ("Exit");
lengthField = new JTextField (5);
lengthLabel = new JLabel ("Enter the length of your pool: ");
widthField = new JTextField (5);
widthLabel = new JLabel ("Enter the width of your pool: ");
depthField = new JTextField (5);
depthLabel = new JLabel ("Enter the depth of your pool: ");
volumeField = new JTextField (5);
volumeLabel = new JLabel ("Volume of the pool: ");
//radio button
ButtonGroup buttonGroup = new ButtonGroup();
builtIn = new JRadioButton ("Built in");
buttonGroup.add(builtIn);
above = new JRadioButton ("Above");
buttonGroup.add(above);
exitButton.setMnemonic('x');
calculateButton.setMnemonic('C');
mainFrame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e)
{ System.exit(0); }
});
// create the handlers
calculateButtonHandler chandler = new calculateButtonHandler(); //instantiate new object
calculateButton.addActionListener(chandler); // add event listener
ExitButtonHandler ehandler = new ExitButtonHandler();
exitButton.addActionListener(ehandler);
FocusHandler fhandler = new FocusHandler();
lengthField.addFocusListener(fhandler);
widthField.addFocusListener(fhandler);
depthField.addFocusListener(fhandler);
}
class calculateButtonHandler implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
DecimalFormat num = new DecimalFormat(", ###.##");
double width;
double length;
double depth;
double volume;
double volume2;
double height;
String instring;
instring = lengthField.getText();
if (instring.equals(""))
{
instring = "0";
lengthField.setText("0");
}
length = Double.parseDouble(instring);
instring = widthField.getText();
if (instring.equals(""))
{
instring = "0";
widthField.setText("0");
}
width = Double.parseDouble(instring);
instring = depthField.getText();
if (instring.equals(""))
{
instring = "0";
depthField.setText("0");
}
depth = Double.parseDouble(instring);
volume = width * length * depth;
volumeField.setText(num.format(volume));
volume2 = width * length * depth;
}
}
class ExitButtonHandler implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
System.exit(0);
}
}
class FocusHandler implements FocusListener
{
public void focusGained(FocusEvent e)
{
if(e.getSource() == lengthField || e.getSource() == widthField || e.getSource() == depthField)
{
volumeField.setText("");
}
else if (e.getSource() == volumeField)
{
volumeField.setNextFocusableComponent(calculateButton);
calculateButton.grabFocus();
}
}
public void focusLost1(FocusEvent e)
{
if(e.getSource() == widthField)
{
widthField.setNextFocusableComponent(calculateButton);
}
}
public void focusLost(FocusEvent e)
{
if(e.getSource() == depthField)
{
depthField.setNextFocusableComponent(calculateButton);
}
}
}
public static void main(String args[])
{
Landscape app = new Landscape();
}
}

Instead of getting the content pane and adding to it, just create a new JPanel and add your stuff to that. Then, add the panel to a new JTabbedPane with whatever title you want, and set the content pane of the JFrame to be the tabbed pane.
Here is a simple example of what you would do:
JPanel panel=new JPanel();//FlowLayout is default
panel.setOpaque(false);//this tells the panel not to draw its background; looks nicer under LAFs where the background inside a tab is different from that of JPanel
panel.add(builtIn);
panel.add(above);
//...you get the picture; add all the stuff you already do, just use panel instead of c
JTabbedPane tabs=new JTabbedPane();
tabs.addTab("title", panel);//add a tab for the panel with the title "title"
//you can add more tabs in the same fashion - obviously you can change the title
tabs.addTab("another tab", comp);//where comp is a Component that will occupy the tab
mainFrame.setContentPane(tabs);//the JFrame will now display the tabbed pane
You can leave the rest of your code how it is and it should work fine.

The tutorial and its demo are pretty straight forward examples.

Related

How to create multiple JPanels with JTextField input?

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.

Refer to an individual JTextField when they're in different tabs

I have three JTextFields, when the buy button is pressed the associated listener should retrieve the text from the text fields and use it to update the table.
The issue is that when I press the buy button it tries to use the data in the JTextFields in David's tab as opposed to the one I'm currently on. If I made another tab named "Jack" it would then try to be using jacks. The code to create the text boxes is as follows:
JLabel label2 = new JLabel("Name Of Share:");
tabPanel.add(label2);
textFieldName = new JTextField("", 15);
textFieldName.setColumns(10);
textFieldName.setToolTipText("Enter Number of shares here");
tabPanel.add(textFieldName);
The listener for the buy button:
int quantity = 0;
if (e.getActionCommand().equals("Buy")) {
String name = view.getTextFieldName().getText();
String ticker = view.getTextFieldTicker().getText().toUpperCase();
try{
quantity = Integer.parseInt(view.getTextFieldNumber().getText());
}catch(NumberFormatException er){
}
view.buy(ticker, name, quantity);
}
Everything works fine if I only have one tab but once I introduce more that's when the issues start.
Can anyone suggest a way to fix this so I can get data from the text boxes of only the tab I am on?
I should have mentioned view is of type MainGUI a Class I have created, which is used for building the GUI which has the fields:
public class MainGUI extends JFrame implements Observer {
private JTabbedPane tabbedPane;
private JTable table;
private JTextField textFieldTicker;
private JTextField textFieldName;
private JTextField textFieldNumber;
private DefaultTableModel model;
private PortfolioManager pm;
private JLabel tValue;
to create a Tab the code used is:
JPanel topPanel = new JPanel();
JPanel buttonPanel = new JPanel();
JPanel labelPanel = new JPanel();
JSplitPane splitPanelbtm = new JSplitPane(JSplitPane.VERTICAL_SPLIT, labelPanel, buttonPanel);
JSplitPane splitPanel = new JSplitPane(JSplitPane.VERTICAL_SPLIT, topPanel, splitPanelbtm){
private final int location = 500;
{setDividerLocation(location);}
#Override
public int getDividerLocation(){
return location;
}
#Override
public int getLastDividerLocation(){
return location;
}
};
splitPanel.setEnabled( false );
splitPanel.setDividerSize(0);
splitPanelbtm.setEnabled( false );
splitPanelbtm.setDividerSize(0);
splitPanelbtm.setBorder(null);
splitPanel.setBorder(null);
tabbedPane.add(tabName, splitPanel);
tabbedPane.setName(tabName);
this.add(tabbedPane);
this.setVisible(true);
createLabelsButtons(topPanel);
createTable(topPanel);
tValue = new JLabel("Total Value for " + tabbedPane.getName() + " is: $ ");
labelPanel.add(tValue);
createTabButtons(buttonPanel);

JPanel doesn't wait for user input before moving on

I'm trying to make a program that will do some fairly simple calculations in a JPanel. One of the requirements is that it will repeat until the user says otherwise. Unfortunately when the JPanel opens it does not wait for any user input, but instead moves right on to the next thing (as I have yet written the part that asks the user if he would like to continue or quit, it's currently in an infinite while loop which means that new JPanels just keep opening continually until I stop the program). My question is: Why isn't the program waiting until the user presses the Okay button to move on?
Here is my main():
public class Driver extends JFrame{
public static void main(String args[]){
do{
new GUI();
while (!GUI.isButtonPressed()){
}
//int choice = JOptionPane.showConfirmDialog(null, "Default tax rate is 7.5%\nDefault discount rate is 10%.\nKeep these default values?", "Choose an Option", JOptionPane.YES_NO_OPTION);
//switch (choice){
//case JOptionPane.YES_OPTION: {
//SaleItem newItem = new SaleItem();
//break;
//}
//case JOptionPane.NO_OPTION: {
//new GUI();
//break;
//}
//}
}while(true);
}
and here is my GUI:
import javax.swing.*;
import java.awt.event.*;
public class GUI extends JFrame {
JPanel panel;
JLabel priceLabel;
JLabel discountLabel;
JLabel taxLabel;
JTextField taxTextField;
JTextField priceTextField;
JTextField discountTextField;
JButton okayButton;
JButton defaultsButton;
final int WINDOW_WIDTH = 300;
final int WINDOW_HEIGHT = 250;
boolean buttonPressed = false;
public boolean isButtonPressed() {
return buttonPressed;
}
public void setButtonPressed(boolean buttonPressed) {
this.buttonPressed = buttonPressed;
}
public GUI(){
super("Item Properties");
setSize(WINDOW_WIDTH, WINDOW_HEIGHT);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
buildPanel();
add(panel);
setVisible(true);
}
private void buildPanel(){
priceLabel = new JLabel("Enter the item price:");
priceTextField = new JTextField(10);
discountTextField = new JTextField(10);
discountLabel = new JLabel("Enter the discount percent:");
taxLabel = new JLabel("Enter the tax percent:");
taxTextField = new JTextField(10);
okayButton = new JButton("Okay");
okayButton.addActionListener(new ButtonListener());
defaultsButton = new JButton("Use Defaults");
defaultsButton.addActionListener(new ButtonListener());
panel = new JPanel();
panel.add(priceLabel);
panel.add(priceTextField);
panel.add(discountLabel);
panel.add(discountTextField);
panel.add(taxLabel);
panel.add(taxTextField);
panel.add(okayButton);
panel.add(defaultsButton);
}
private class ButtonListener implements ActionListener {
private boolean buttonPressed = false;
public void actionPerformed(ActionEvent event){
GUI.setButtonPressed(true);
SaleItem newItem = new SaleItem(Double.parseDouble(priceTextField.getText()), Double.parseDouble(discountTextField.getText()), Double.parseDouble(taxTextField.getText()));
}
}
The stuff about getButtonPressed() and isButtonPressed() and all that was me trying (unsuccessfully) to solve the problem on my own.
Thanks in advance for any help!
Unfortunately when the JPanel opens it does not wait for any user input,
Panels don't open. You add a panel to a frame or dialog. If you want something to "open" or "popup" then you use a JDialog.
SaleItem newItem = new SaleItem(...);
SaleItem should be a modal JDialog. Then the dialog will not close until the user clicks on button that you create to close the dialog. A dialog is created exactly the same way as you create a JFrame.

Change JTextArea texts from JButton's actionPerformed which is in another class

I have a fully functional console-based database which I need to add GUIs to. I have created a tab page (currently only one tab) with a button "Display All Student" which when triggered will display a list of students inside a JTextArea which of course is in its own class and not inside the button's action listener class. Problem is, the JTextArea is not recognised inside button's action listener. If I add parameter into the action listener, more errors arise. Help?
I have searched Stack Overflow for similar problems but when I tried it in my code, doesn't really do the trick? Or maybe I just need a nudge in the head. Anyways.
Here is my code so far:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class StudDatabase extends JFrame
{
private JTabbedPane tabbedPane;
private JPanel studentPanel;
private static Scanner input = new Scanner(System.in);
static int studentCount = 0;
static Student studentArray[] = new Student[500];
public StudDatabase()
{
setTitle("Student Database");
setSize(650, 500);
setBackground(Color.gray);
JPanel topPanel = new JPanel();
topPanel.setLayout( new BorderLayout() );
getContentPane().add( topPanel );
// Create the tab pages
createStudentPage();
// more tabs later...
// Create a tab pane
tabbedPane = new JTabbedPane();
tabbedPane.addTab( "Student Admin", studentPanel );
topPanel.add( tabbedPane, BorderLayout.CENTER );
}
public void createStudentPage()
{
studentPanel = new JPanel();
studentPanel.setLayout(new FlowLayout(FlowLayout.CENTER));
JButton listButton = new JButton("List All Student(s)");
listButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
if(studentCount > 0)
{
for(int i=0; i<studentCount; i++)
{
// print out the details into JTextArea
// ERROR! textDisplay not recognised!!!
textDisplay.append("Student " + i);
}
System.out.printf("\n");
}
else // no record? display warning to user
{
System.out.printf("No data to display!\n\n");
}
}
});
studentPanel.add(listButton);
JTextArea textDisplay = new JTextArea(10,48);
textDisplay.setEditable(true); // set textArea non-editable
JScrollPane scroll = new JScrollPane(textDisplay);
scroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
studentPanel.add(scroll);
}
public static void main(String[] args)
{
StudDatabase mainFrame = new StudDatabase();
mainFrame.setVisible(true);
}
Your code isn't working for the same reason this wouldn't work:
int j = i+5;
int i = 4;
You have to declare variables before using them in Java.
Secondly, in order to use a variable (local or instance) from inside an inner class - which is what your ActionListener is - you need to make it final.
So, the below code will compile and run:
final JTextArea textDisplay = new JTextArea(10,48);
...
listButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
...
textDisplay.append("Student " + i);

Limit the number of selected JToggleButton

I'm new on swing java, I maked an array of jtoggle buttons and my problem is that I want to limit the number of selected(toggled) buttons for 4 toggled buttons. Is there any property that allows me to do that ?
Here is my code example.
package adad;
import java.awt.*; import java.awt.event.*;
import javax.swing.*;
public class essayer extends JFrame
{
private JToggleButton jb_essai[] = new JToggleButton[6];
JButton pressme = new JButton("Press Me");
essayer() // the frame constructor
{
super("Toggle boutons");
setBounds(100,100,300,200);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container con = this.getContentPane();
JPanel pane = getContainer();
con.add(pane);
setVisible(true);
}
class ToggleAction implements ActionListener
{
private JToggleButton jb_essai[];
public ToggleAction(JToggleButton a_jb_essai[])
{
jb_essai = a_jb_essai;
}
public void actionPerformed(ActionEvent e)
{
String etatBoutons = "";
int size = jb_essai.length;
for(int i=0;i<size;i++)
{
String tmp = "Bouton "+(i+1)+" : ";
if(jb_essai[i].isSelected()==true )
{
tmp+="enfonce";
}
else
{
tmp+="relache";
}
tmp+="\n";
etatBoutons +=tmp;
}
System.out.println(etatBoutons+"\n---------");
}
}
private JPanel getContainer()
{
GridLayout thisLayout = new GridLayout(6,2);
JPanel container = new JPanel();
ToggleAction tga = new ToggleAction(jb_essai);
container.setLayout(thisLayout);
int j=6;
for (int i=0;i<j;i++)
{
String s = String.valueOf(i+1);
container.add(jb_essai[i]= new JToggleButton(s)); // actuellement tt s'affiche sur un même colone.
jb_essai[i].addActionListener(tga);
}
return container;
}
public static void main(String[] args) {new essayer();}
}
Is there any property that allows me to do that ?
No. There is a ButtonGroup that allows 'one of many'. But that is 1, not N of many. Anything beyond that you'll need to code yourself.
Is there any property that allows me to do that ?
No, you need to write your own code.
Add a common ItemListener to every toggle button. Then when a button is selected you loop though your toggle button array to count the number of selected toggle buttons.
If the count is greater than 4 then you display a JOptionPane with an error message and your reset the last selected button to be unselected. You can use the getSource() method of the ItemListener to get the toggle button.
Or maybe you can extend the ButtonGroup class to implement similar behaviour.

Categories

Resources