JScrollPane isn't working in GUI - java

OK, I am trying to create a GUI that has a JScrollPane that, through the JTextArea, will print out an array of ints, one line at a time. I am using some methods I created for an assignment to deal with the data, and have one of them working on the data in the following example, (I can't show the methods because it's homework that isn't due yet). The methods have been tested and work fine, so no need for them in this question. So far, either the text area will show up in the GUI, but not have the scroll pane attached to it, or only the jlabel will show up with the results of the work done via the method. Can someone have a look at my code and tell me what I am doing wrong, because I have gone over this like 50 times, and cannot get the GUI to behave.
public class MyClassName extends JFrame{
private JScrollPane myScroll;
private JTextArea myTextArea;
private JLabel myMean;
private JLabel myMedian;
private JLabel myMax;
private JLabel myMin;
private JLabel mySum;
private Container content;
private Font myFont;
private SpringLayout layout;
private MyClassName() {
this(500,300,"TEST TITLE");
}
private MyClassName(int width, int height, String title)
{
this.setVisible(true);
this.setTitle(title);
this.setSize(width, height);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
guiComponent();
}
public void guiComponent()
{
layout = new SpringLayout();
content = this.getContentPane();
int [] test = {50,37,43,12,8,16,32,44,78,92,1,3,66,34};
myTextArea = new JTextArea();
myScroll = new JScrollPane(myTextArea);
content.add(myScroll);
myMean = new JLabel("MEAN : " + MyClassName.mean(test));
for(int count : test)
{
String z = Integer.toString(count);
myTextArea.append('\n' + z);
}
myFont = new Font("Serrif", Font.BOLD, 30);
myMean.setFont(myFont);
content.add(myScroll);
layout.putConstraint(SpringLayout.WEST, myScroll, 20, SpringLayout.WEST, content);
layout.putConstraint(SpringLayout.NORTH, myScroll, 25, SpringLayout.NORTH, content);
content.add(myMean);
layout.putConstraint(SpringLayout.WEST, myMean, 20, SpringLayout.EAST, myScroll);
layout.putConstraint(SpringLayout.NORTH, myMean, 25, SpringLayout.NORTH, content);
}
public static double mean(int[] ar) {
double x = 0;
for (int i = 0; i < ar.length; i++) {
x += ar[i];
}
return x / ar.length;
}
public static void main(String[] args) {
MyClassName test2 = new MyClassName();
}

Your problem when you need to display the components in layout, to solve your problem add those three line after initialize 'myTextArea' component:
myTextArea.setColumns(20);
myTextArea.setRows(5);
getContentPane().setLayout(layout);
you maybe need to read this link about Layout.

Related

How to also change int if Jlabel is changed

I am trying to figure out how I can also change my int if my Jlabel is changed. I tried to use AtomicInteger and it works if I only want to change n1, but how do I make it that it looks at the label and then changes the correct int? At the moment I have n1 - n3, but in the future that will be 30.
This is my code at the moment:
public class GUI {
JLabel currentEditLabel = null;
JFrame frame;
int n1 = 6;
int n2 = 5;
int n3 = 8;
GUI() {
frame = new JFrame();//creating instance of JFrame
JLabel l1 = new JLabel(Integer.toString(n1));
JLabel l2 = new JLabel(Integer.toString(n2));
JLabel l3 = new JLabel(Integer.toString(n3));
JTextField t = new JTextField();
l1.setBounds(40, 50, 100, 40);
l2.setBounds(40, 100, 100, 40);
l3.setBounds(40, 150, 100, 40);
t.setBounds(20, 200, 100, 40);
frame.add(l1);
frame.add(l2);
frame.add(l3);
frame.add(t);
t.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (currentEditLabel != null) {
currentEditLabel.setText(t.getText());
AtomicInteger level = new AtomicInteger(Integer.parseInt(currentEditLabel.getText()));
n1 = level.intValue();
currentEditLabel = null;
}
}
});
addMouseListener(l1, t);
addMouseListener(l2, t);
addMouseListener(l3, t);
frame.setSize(400, 500);//400 width and 500 height
frame.setLayout(null);//using no layout managers
frame.setVisible(true);//making the frame visible
}
private void addMouseListener(JLabel label, JTextField t) {
label.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
currentEditLabel = (JLabel) e.getComponent();
t.setText(currentEditLabel.getText());
}
});
}
public static void main(String[] args) {
new GUI();
}
}
AtomicInteger? You're barking up the wrong tree since this won't help you in the least.
Your n1 value does in fact change within the listener, but you're not changing the JLabel text at all, and that is what you need to do:
In the MouseListener, also call setText(...) on whatever JLabel (the one clicked perhaps) that you wish to have the text display change on.
While the l1 JLabel's displayed text is created using n1's value, note that if n1 ever changes, l1
s text will not change on its own. Again, if you wish to change l1's text, you must do so with code, calling .setText(...) on it.
Some suggestions based on your new requirements:
Create an array of int to hold the int values
Create a List<JLabels> to hold all the JLabels that will display the values held in the above collection of numbers
Create your JLabels in a for loop that loops through all the ints, and fill each JLabel with the appropriate number text
In that same for loop, add your JLabels to the JLabel-list mentioned above
Add a MouseListener (I usually use a MouseAdapter for this) to each JLabel in the for loop
Pass the for loop's index into your MouseListener's constructor to set a field of the class, so that the index of the selected JLabel is readily available
Use a JSpinner and SpinnerNumberModel to display the changable text
In the MouseLister, set the value that the spinner holds
Add a ChangeListener to the spinner so that when the numeric value changes, you update the appropriate JLabel with the new value
You will need to also remove the above ChangeListener before setting the spinner's value in the mouse listener and then re-add the same listener immediately after making this change.
Do not use AtomicInteger as it is completely unnecessary and is somewhat misleading to you
Avoid using null layouts but instead use layout managers
Proof of concept:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
#SuppressWarnings("serial")
public class GUI2 extends JPanel {
private static final Border UNSELECTED_BORDER = BorderFactory.createLineBorder(Color.LIGHT_GRAY, 3);
private static final Border SELECTED_BORDER = BorderFactory.createLineBorder(Color.PINK, 3);
private int[] intArray = { 6, 5, 8, 13, 17, 22, 55, 33, 2, 0, 23, 51, 0, 111, 200, 6, 5, 8, 13, 17, 22, 55, 33, 2,
0, 23, 51, 0, 111, 200, 6, 5, 8, 13, 17, 22, 55, 33, 2, 0, 23, 51, 0, 111, 200 };
private SpinnerNumberModel spinnerModel = new SpinnerNumberModel(0, 0, 10000, 1);
private JSpinner intSpinner = new JSpinner(spinnerModel);
private ChangeListener spinnerListener = new SpinnerListener();
private List<JLabel> labelList = new ArrayList<>();
private int selectedIndex = -1;
public GUI2() {
JPanel topPanel = new JPanel();
topPanel.add(new JLabel("Current Selected Value:"));
topPanel.add(Box.createHorizontalStrut(5));
topPanel.add(intSpinner);
intSpinner.addChangeListener(spinnerListener);
int gap = 3;
JPanel labelGridPanel = new JPanel(new GridLayout(0, 5, gap, gap));
for (int i = 0; i < intArray.length; i++) {
String text = String.valueOf(intArray[i]);
JLabel label = new JLabel(text);
label.setBorder(UNSELECTED_BORDER);
label.addMouseListener(new MyMouse(i));
labelGridPanel.add(label);
labelList.add(label);
}
setBorder(BorderFactory.createEmptyBorder(gap, gap, gap, gap));
setLayout(new BorderLayout(gap, gap));
add(topPanel, BorderLayout.PAGE_START);
add(labelGridPanel, BorderLayout.CENTER);
}
private class MyMouse extends MouseAdapter {
private int index;
public MyMouse(int index) {
this.index = index;
}
#Override
public void mousePressed(MouseEvent e) {
selectedIndex = index;
JLabel label = labelList.get(index);
int currentValue = Integer.parseInt(label.getText());
// remove change listener before making this change
intSpinner.removeChangeListener(spinnerListener);
intSpinner.setValue(currentValue);
// then re-add the change listener after
intSpinner.addChangeListener(spinnerListener);
// show by border which JLabel has been selected
for (JLabel jLabel : labelList) {
// first make all borders the default border
jLabel.setBorder(UNSELECTED_BORDER);
}
// then set the selected border
labelList.get(index).setBorder(SELECTED_BORDER);
}
}
private class SpinnerListener implements ChangeListener {
#Override
public void stateChanged(ChangeEvent e) {
// if we have not yet selected a JLabel, get out of here
if (selectedIndex < 0) {
return;
}
int value = (int) spinnerModel.getValue();
labelList.get(selectedIndex).setText(Integer.toString(value));
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
GUI2 mainPanel = new GUI2();
JFrame frame = new JFrame("GUI");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
}
In your code, you only update n1 regardless of which label is the currentEditLabel.
Your code:
currentEditLabel.setText(t.getText());
AtomicInteger level = new AtomicInteger(Integer.parseInt(currentEditLabel.getText()));
n1 = level.intValue();
currentEditLabel = null;
Solution: You need to know which label is the currentEditLabel so that you can update the correct variable. Your action listener will need access to l1, l2 and l3. So, instead of defining them in the constructor, define them as instance variables same way you defined n1, n2, and n3.
currentEditLabel.setText(t.getText());
AtomicInteger level = new AtomicInteger(Integer.parseInt(currentEditLabel.getText()));
if (currentEditLabel == l1)
n1 = level.intValue();
else if (currentEditLabel == l2)
n2 = level.intValue();
else
n3 = level.intValue();
currentEditLabel = null;

How to increase the width of JTextField in Tab?

In Food Tab, I want to achieve this
But I only able to get this
How can I increase the width of the JTextField which are in Food Tab ? Below is my code
public class FoodOrdering {
static private JFrame frame;
static private JTextField textField;
static private GridBagConstraints gbc;
static private JLabel[] foodLabel;
static private JLabel[] labels;
static private JTextField[] qtyField;
static private JLabel[] foodImage;
static private File[] file;
private static final int ELEMENTS = 9;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
FoodOrdering window = new FoodOrdering();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*
* #throws IOException
*/
public FoodOrdering() throws IOException {
initialize();
}
/**
* Initialize the contents of the frame.
*
* #throws IOException
*/
static void initialize() throws IOException {
frame = new JFrame();
frame.setBounds(100, 100, 700, 550);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
frame.setLocationRelativeTo(null);
JLabel lblFoodOrdered = new JLabel("Food Ordered");
lblFoodOrdered.setBounds(529, 11, 81, 14);
frame.getContentPane().add(lblFoodOrdered);
TextArea textArea = new TextArea();
textArea.setBounds(462, 31, 199, 275);
frame.getContentPane().add(textArea);
JLabel lblTotal = new JLabel("Total : ");
lblTotal.setBounds(519, 315, 46, 14);
frame.getContentPane().add(lblTotal);
textField = new JTextField();
textField.setBounds(575, 312, 86, 20);
frame.getContentPane().add(textField);
textField.setColumns(10);
JButton btnOrder = new JButton("Order");
btnOrder.setBounds(521, 352, 89, 23);
frame.getContentPane().add(btnOrder);
JTabbedPane tabbedPane = new JTabbedPane(JTabbedPane.TOP);
addIt(tabbedPane, "Foods");
addIt1(tabbedPane, "Drinks");
addIt1(tabbedPane, "Desserts");
tabbedPane.setBounds(23, 11, 400, 450);
frame.getContentPane().add(tabbedPane);
frame.setVisible(true);
}
static void addIt1(JTabbedPane tabbedPane, String text) {
JLabel label = new JLabel(text);
JButton button = new JButton(text);
JPanel panel = new JPanel();
panel.add(label);
panel.add(button);
tabbedPane.addTab(text, panel);
}
static void addIt(JTabbedPane tabbedPane, String text) throws IOException {
JPanel panel = new JPanel(new GridBagLayout());
gbc = new GridBagConstraints();
gbc.insets = new Insets(1, 1, 1, 1);
foodImage = new JLabel[ELEMENTS];
foodLabel = new JLabel[ELEMENTS];
labels = new JLabel[ELEMENTS];
qtyField = new JTextField[ELEMENTS];
file = new File[ELEMENTS];
try {
file[0] = new File("C:\\Users\\tony\\Desktop\\MedSalad.png");
file[1] = new File("C:\\Users\\tony\\Desktop\\JapanesePanNoodles.png");
file[2] = new File("C:\\Users\\tony\\Desktop\\Spaghetti.png");
file[3] = new File("C:\\Users\\tony\\Desktop\\PadThai.png");
file[4] = new File("C:\\Users\\tony\\Desktop\\RamenNoodles.png");
file[5] = new File("C:\\Users\\tony\\Desktop\\SpaghettiAndMeatBalls.png");
file[6] = new File("C:\\Users\\tony\\Desktop\\chickenRice.jpg");
file[7] = new File("C:\\Users\\tony\\Desktop\\thaiFood.jpeg");
file[8] = new File("C:\\Users\\tony\\Desktop\\vietnamFood.jpg");
foodLabel[0] = new JLabel("Salad");
foodLabel[1] = new JLabel("Japanese Noodles");
foodLabel[2] = new JLabel("Spaghetti");
foodLabel[3] = new JLabel("Spaghetti Meat Balls");
foodLabel[4] = new JLabel("Noodles");
foodLabel[5] = new JLabel("Kids Spaghetti");
foodLabel[6] = new JLabel("Chicken Rice");
foodLabel[7] = new JLabel("Thai Food");
foodLabel[8] = new JLabel("Vietnam Food");
} catch (Exception e) {
e.printStackTrace();
}
for (int i = 0; i < ELEMENTS; i++) {
Image image = ImageIO.read(file[i]);
Image imageScaled = image.getScaledInstance(80, 95, Image.SCALE_SMOOTH);
ImageIcon imageIcon = new ImageIcon(imageScaled);
qtyField[i] = new JTextField(3);
foodImage[i] = new JLabel(imageIcon);
}
gbc.gridx = 0;
for (int i = 0; i < ELEMENTS; i++) {
if (i % 3 == 0) {
gbc.gridy += 2;
gbc.gridx = 0;
}
panel.add(foodImage[i], gbc);
gbc.gridy++;
panel.add(foodLabel[i], gbc);
gbc.gridy--;
gbc.gridx++;
panel.add(qtyField[i], gbc);
gbc.gridx++;
tabbedPane.addTab(text, panel);
}
}
public void setVisible(boolean b) throws IOException {
}
}
The JTextfield objects are so narrow because of a very old "bug" in GridBagLayout which causes it to ignore the preferred size of its contents.
There are several possible ways to work-around this bug:
Create a class called PreferredGridBagLayout as explained in the link and use that instead of GridBagLayout.
Set the minimum size of each of your qtyField instances with qtyField[i].setMinimumSize(qtyField[i].getPreferredSize()).
Create subclasses of JTextField which override the method getMinimumSize() to return the same value as getPreferredSize(), or some other reasonable minimum size.
Because this problem is so common when using GridBagLayout, solution #1 is the easiest in the long term.
Afterwards, you'll need to make your tabbedPane object a little wider, or switch to a layout manager in the main panel that automatically determines the size of the tabbed pane.
There are multiple things that could be improved in your code. Creating good layouts in Swing is not easy, and you will need much more work to make a pretty layout. But this will solve your problem with collapsing text fields.
This problem simply can be solved by setting the
qtyField[i].setMinimumSize(new Dimension(33,20));
function. The reason for setting minimum size is that the GridBagLayout dont have enough space to arrange all those components properly so it only takes the minimum size of the empty textField.
Just add the code after the line
qtyField[i] = new JTextField(3);
and you will be also needed to increase the width of tabbedPane a little bit more to make the components(qtyField) visible
Instead of using null layout. use some other layout like border layout. Then use just one line:
frame.pack();
This will display all the components at their preferred sizes.
Just a coding practice: instead of setting bounds use panels to add components and then add these panels to a main panel.
Like use one different panel to add your Jlabel of food ordered, textarea, Jlabel for order and order button. And then add that panel to your main panel.
Hope you understand. :)

Accessing Jtextfield from outer action listener

I am trying to access JTextField text namely 'searchBox' from outer action listener created in outer class.
GUI:
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class MyFrame extends JFrame
{
public int stat1_var;
public int stat2_var;
public int stat3_var;
public String stat4_var;
private int statX_bound = 50;
private int statY_bound = 280;
public String url;
/*
* #param width The width of the frame.
* #param height The height of the frame.
* #param title The title of the frame.
*/
public MyFrame(int width, int height, String title, int stat1_var, int stat2_var, int stat3_var, String stat4_var)
{
this.stat1_var = stat1_var; //threading var
this.stat2_var = stat2_var; //spiders var
this.stat3_var = stat3_var; //results var
this.stat4_var = stat4_var; //other var
initUI(width, height, stat1_var, stat2_var, stat3_var, stat4_var);
this.setSize(width,height); //set frame size
this.setTitle(title); //set frame title
this.setVisible(true); //set visible
this.setResizable(false); //disable resizable frame
}
private void initUI(int width, int height, int stat1_var, int stat2_var, int stat3_var, String stat4_var)
{
ImageIcon ic = new ImageIcon("background.jpg");//background image source
JDesktopPane dp = new JDesktopPane(); //create desktop pane
JLabel lbl = new JLabel(ic); //create label
JPanel transparentPanel = new JPanel(); //create a JPanel
lbl.setBounds(0, 0, width, height); //bounds for the background
transparentPanel.setOpaque(false);
transparentPanel.setBounds(0, 0, width, height);//bounds for the panel
transparentPanel.setLayout(null);//default layout
setLayeredPane(dp);
JTextField searchBox = new JTextField("http://", 40); //keyword search box
searchBox.setEditable(true);
searchBox.setBounds(250, 130, 300, 25);
searchBox.setToolTipText("Enter domain to be crawled");
transparentPanel.add(searchBox);
searchBox.setActionCommand("url");
searchBox.addActionListener(new listeners(this));
JButton crawlBtn = new JButton("Crawl"); // search button
crawlBtn.addActionListener(new listeners(this));
crawlBtn.setBounds(555, 130, 80, 25);
crawlBtn.setActionCommand("crawl");
crawlBtn.setToolTipText("crawl domain");
transparentPanel.add(crawlBtn);//end
JTextField searchBox2 = new JTextField("", 40); //crawl url search box
searchBox2.setEditable(true);
searchBox2.setBounds(250, 160, 300, 25);
searchBox2.setToolTipText("enter your keywords");
transparentPanel.add(searchBox2); //end
JButton jumpBtn = new JButton("Jump!"); // search button
jumpBtn.addActionListener(new listeners(this));
jumpBtn.setBounds(555, 160, 80, 25);
jumpBtn.setActionCommand("crawl");
jumpBtn.setToolTipText("crawl domain");
transparentPanel.add(jumpBtn);//end
JLabel stat1 = new JLabel("Threads: " + stat1_var); //stat labels
stat1.setToolTipText("Threads");
stat1.setBounds(statX_bound, statY_bound, 300, 25);
statY_bound += 25; //place the label one place below
transparentPanel.add(stat1);
JLabel stat2 = new JLabel("Spiders: " + stat2_var); //stat labels
stat2.setToolTipText("Spiders");
stat2.setBounds(statX_bound, statY_bound, 300, 25);
statY_bound += 25; //place the label one place below
transparentPanel.add(stat2);
JLabel stat3 = new JLabel("Results found: " + stat3_var);
stat3.setToolTipText("Results found");
stat3.setBounds(statX_bound, statY_bound, 300, 25);
statY_bound += 25; //place the label one place below
transparentPanel.add(stat3);
JLabel stat4 = new JLabel("Status: " + stat4_var);
stat4.setToolTipText("Status");
stat4.setBounds(statX_bound, statY_bound, 300, 25);
statY_bound += 25; //place the label one place below
transparentPanel.add(stat4);
dp.add(lbl,new Integer(50));
dp.add(transparentPanel,new Integer(350));
setDefaultCloseOperation(EXIT_ON_CLOSE); //close the app if close button clicked
} //end constructor
public void paint(Graphics g)
{
super.paint(g); //call superclass' paint method
g.setColor(Color.BLACK);
} //end method paint
} //end class MyFrame
And this is the outer class listener:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.PrintWriter;
import java.io.File;
public class listeners implements ActionListener
{
private MyFrame myframe;
public listeners(MyFrame myframe){
this.myframe = myframe;
//String source = e.getSource();
}
public void actionPerformed(ActionEvent event) {
String action = event.getActionCommand();
if (action == "url")
{
myframe.url = searchBox.getText(); //<----- I am trying to obtain this from the gui
}
}
}
I am trying to obtain the searchBox text value(arrows above) to the url variable from GUI class. Can anyone please help me with this? I have been looking for the solution for 3 hours now...
Use getSource to obtain a reference to the JTextField
JTextField searchBox = (JTextField) e.getSource();
Declare your JTextField variable as instance var. (outside of initUI method) and create getter method. Then call it in your listeners class:
myframe.url = myframe.getSearchBox().getText();;
Other sidenotes:
Name your classes properly. Names of classes begin with upper cases.
Do not extend your class with JFrame if you are not going to override some methods or to define new methods.
DON'T use absolute positioning for swing components! Use proper layout manager.

Trouble updating my JFrame

I'm kind of new to java, so go easy. I'm trying to make a simple game where everytime you click a button it adds one to a variable. That all works fine, but i'm also trying to display the variable to my JFrame. This is where the trouble comes, I click the button, it does add one to my variable (I printed the variable to the console to be sure) but the JFrame isn't updating the variable. I should also note, when you first open the game, it opens a window allowing you to type a username, this is in a separate class, which contains my main method. Here is my code for my second window, the one with the problem:
import javax.swing.BorderFactory;
public class Game extends JFrame {
private static final long serialVersionUID = 1L;
private JPanel contentPane;
private String name;
public static int pennies = 0;
public static int dollars = 0;
public static int moneyAddRate = 1;
private JButton btnAddMoney = new JButton(new ImageIcon("C:\\Users\\Tanner\\git\\Money-Bags\\res\\coins\\oneCent.png"));
private Border emptyBorder = BorderFactory.createEmptyBorder();
public Game(String name) {
this.name = name;
createWindow();
}
private void createWindow() {
setTitle(name + "'s Economy");
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(800, 600);
setLocationRelativeTo(null);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
btnAddMoney.setBounds(329, 244, 96, 96);
btnAddMoney.setBorder(emptyBorder);
contentPane.add(btnAddMoney);
btnAddMoney.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
addMoney();
}
});
JLabel lblPennies = new JLabel("You have " + pennies + " Pennies");
lblPennies.setBounds(10, 11, 152, 24);
contentPane.add(lblPennies);
JLabel lblDollars = new JLabel(dollars + " Dollars");
lblDollars.setBounds(10, 70, 152, 24);
contentPane.add(lblDollars);
JLabel lblAnd = new JLabel("&");
lblAnd.setBounds(10, 45, 61, 14);
contentPane.add(lblAnd);
setVisible(true);
}
private void addMoney() {
pennies += moneyAddRate;
System.out.println(pennies + " " + dollars);
contentPane.validate();
contentPane.repaint();
}
}
It isn't updating because you aren't updating any Component with the new pennies amount. Your addMoney() method should look something like this:
private void addMoney() {
pennies += moneyAddRate;
lblPennies.setText(String.format("You have %d pennies", pennies));
lblPennies.repaint();
}

JTextPane not updating after values changed

Code is underneath. Basically what I'm trying to do is I have display going on in my JPanel of a JTextPane. I have a button that edits the value of the string that's supposed to be displayed in the JTextPane. I can't figure out how to update the JTextPane however. I've tried revalidate(), validate(), repaint(), none of those seemed to work.
The code is complete, it should be able to run.
import java.awt.Canvas;
public class windowBuild extends JFrame {
/**
*
*/
private static final long serialVersionUID = 1L;
private JPanel contentPane;
private int health = 20;
private int energy = 4;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
windowBuild frame = new windowBuild();
frame.setVisible(true);
}
});
}
private class ButtonHandler implements ActionListener {
public void actionPerformed(ActionEvent e) {
String which = e.getActionCommand();
if (which.equals("Claw")){
energy = energy-1;
System.out.println("Player one's dragon clawed the opponent. Dragon's energy is now at: "+ energy);}
else if (which.equals("Wait")){
System.out.println("Turn succesfully skipped");}
System.out.println(getEnergy());
}
}
public windowBuild() {
ButtonHandler bh;
System.out.println("Starting frame...");
bh = new ButtonHandler();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 800, 600);
contentPane = new JPanel();
contentPane.setBorder(new TitledBorder(null, "Dragon Duel",
TitledBorder.CENTER, TitledBorder.TOP, null, Color.CYAN));
setContentPane(contentPane);
contentPane.setLayout(null);
JButton btnClaw = new JButton("Claw");
btnClaw.setBounds(288, 511, 109, 39);
contentPane.add(btnClaw);
btnClaw.addActionListener(bh);
if (energy == 0)
btnClaw.setEnabled(false);
JButton btnWait = new JButton("Wait");
btnWait.setBounds(645, 511, 109, 39);
contentPane.add(btnWait);
btnWait.addActionListener(bh);
StringBuilder sb = new StringBuilder();
String strB = Integer.toString(health);
sb.append("H: ").append(strB).append("/20");
String healthString = sb.toString();
JTextPane txtpnH_1 = new JTextPane();
txtpnH_1.setEditable(false);
txtpnH_1.setFont(new Font("Impact", Font.PLAIN, 30));
txtpnH_1.setText(healthString);
txtpnH_1.setBounds(134, 511, 109, 39);
contentPane.add(txtpnH_1);
String strR = Integer.toString(energy);
String energyString = "E: ";
energyString += strR;
energyString += "/4";
JTextPane txtpnH = new JTextPane();
txtpnH.setEditable(false);
txtpnH.setText(energyString);
txtpnH.setFont(new Font("Impact", Font.PLAIN, 30));
txtpnH.setBounds(39, 511, 85, 39);
contentPane.add(txtpnH);
}
}
Thanks so much!!
Take the time to read through the Code Conventions for the Java Programming Language
Make use of appropriate layout managers, see A Visual Guide to Layout Managers and Using Layout Managers for more details
For what it's worth, use JTextField instead JTextPane, you're gaining little to no benefit by using JTextPane for what you seem to be trying to achieve. In fact, you might actually be better of us just using JLabel, seen as you don't want them to be editable
Avoid overriding top level containers, like JFrame, instead start with something like JPanel, build your UI on it and then deploy it to what ever top level container you want.
The problem you have is a reference issue. In the constructor of your windowBuild, you are defining all your UI components. This means that there is no way you can reference them anywhere else from with your program. Instead, make those components you need to reference else where instance fields.
public class WindowBuild extends JFrame {
//...//
private JTextPane txtpnH_1;
private JTextPane txtpnH;
//...//
public WindowBuild() {
//...//
txtpnH_1 = new JTextPane();
//...//
txtpnH = new JTextPane();
//...//
}
private class ButtonHandler implements ActionListener {
public void actionPerformed(ActionEvent e) {
String which = e.getActionCommand();
// Now you can use txtpnH_1.setText and txtpnH.setText
}
}

Categories