I have a panel for adding an item to the cart. For example:
public class SomePanel extends JPanel {
private static final long serialVersionUID = 1L;
private JLabel firstLabel;
private JLabel secondNameLabel;
private JLabel thirdLabel;
// and more..
private JTextField firstTextField;
private JTextField firstTextField;
private JTextField thirdTextField;
// and more..
private void init() {
firstLabel = new JLabel("First label");
secondLabel = new JLabel("Second label");
thirdLabel = new JLabel("Third label");
// and more..
firstTextField = new JTextField("first field");
secondTextField = new JTextField("second field");
thirdTextField = new JTextField("third field");
// and more..
}
This panel is located in the dialog. When I select "Add" in the menu, a dialog and this panel appear. There I can enter information about the product and add the product.
The problem is that I have another three areas on the main form. These areas also display the same panel as above. How can I reuse an existing SomePanel and would this be a good practice? Maybe it's better to create singletons for each element (JLabel and JTextField) instead?
Maybe there is some special pattern for solving this problem?
It is an excellent suggestion to re-use the panel object, and it doesn't just work for a fixed number of fields, you can do it with a dynamic number of fields as well.
You have already created a wrapper around a JPanel, so we can simply add a method to it that will update the panel to display the new contents. In this case I have created a new method create(...) that will update the contents.
For example, if you have a fixed number of fields it might look something like this:
public class SomePanel extends JPanel {
private static final long serialVersionUID = 1L;
final int labelHeight = 10;
final int fieldHeight = 20;
private JLabel firstLabel = createLabel("label 1", 0, 0);
private JLabel secondLabel = createLabel("label 2", 0, 30);
private JLabel thirdLabel = createLabel("label 3", 0, 60);
// and more..
private JTextField firstTextField = createField(null, 0, 10);
private JTextField secondTextField = createField(null, 0, 40);
private JTextField thirdTextField = createField(null, 0, 70);
// and more..
//New method to udpate the contents
public boolean create(List<String> labels, List<String> textFields) {
if(labels.size() != textFields.size()){
System.out.println("Failed to update panel, there was a different number of labels and fields");
return false;
}
//Update the fixed label and field values
firstLabel.setText(labels.get(0));
secondLabel.setText(labels.get(1));
thirdLabel.setText(labels.get(2));
firstTextField.setText(textFields.get(0));
firstTextField.setText(textFields.get(1));
firstTextField.setText(textFields.get(2));
//Make sure that this panel is visiable after updating the values
this.setVisible(true);
//Success, return true
return true;
}
//Remove the x and y depending on the layout manager
private JLabel createLabel(String name, int x, int y){
//Create label
JLabel label = new JLabel(name);
//Set location and size or use a layour manager
label.setLocation(x, y);
label.setSize(50, labelHeight);
//Configure cutsom label settings
//label.setFont(...);
//label.setBorder(...);
//return the custom label
return label;
}
//Remove the x and y depending on the layout manager
private JTextField createField(String content, int x, int y) {
//Create label
JTextField field = new JTextField();
if(content != null){
field.setText(content);
}
//Set location and size or use a layour manager
field.setLocation(x, y);
field.setSize(80, fieldHeight);
//Configure cutsom text field settings
//field.setFont(...);
//field.setBorder(...);
//return the custom field
return field;
}
}
Or if you want to get fancy with dynamic content with a flexible number of labels and fields you could do something like this:
public class SomePanel extends JPanel {
private static final long serialVersionUID = 1L;
final int labelHeight = 10;
final int fieldHeight = 20;
final int padding = 5;
//Keep a list of contents only if you need to edit/retreive data from the panel
private List<JTextField> fieldList = new ArrayList<>();
//New method to udpate the contents
public boolean create(List<String> labels, List<String> textFields) {
if(labels.size() != textFields.size()){
System.out.println("Failed to update panel, there was a different number of labels and fields");
return false;
}
//remove previous components
this.removeAll();
//reset the dynamic lists (For if you need to edit/retreive data from the panel)
fieldList = new ArrayList<>();
//placement values (remove these if using a layout manager)
int xPos = 0;
int yPos = 0;
//Update the lists based on the new values
for (int count = 0; count < labels.size(); count++) {
//Create and add labels
JLabel dynamicLabel = createLabel(labels.get(count), xPos, yPos);
this.add(dynamicLabel);
//update placement location, remove if you use a layout manager
yPos += labelHeight + padding;
//Create and add fields
JTextField dynamicField = createField(textFields.get(count), xPos, yPos);
this.add(dynamicLabel);
//update placement location, remove if you use a layout manager
yPos += fieldHeight + padding;
//Store fields in a list so that we can retreive the contents later if needed, or if
fieldList.add(dynamicField);
}
//Make sure that this panel is visiable after updating the values
this.setVisible(true);
//Success, return true
return true;
}
//Remove the x and y depending on the layout manager
private JLabel createLabel(String name, int x, int y){
//Create label
JLabel label = new JLabel(name);
//Set location and size or use a layour manager
label.setLocation(x, y);
label.setSize(50, labelHeight);
//Configure cutsom label settings
//label.setFont(...);
//label.setBorder(...);
//return the custom label
return label;
}
//Remove the x and y depending on the layout manager
private JTextField createField(String content, int x, int y) {
//Create label
JTextField field = new JTextField();
if(content != null){
field.setText(content);
}
//Set location and size or use a layour manager
field.setLocation(x, y);
field.setSize(80, fieldHeight);
//Configure cutsom text field settings
//field.setFont(...);
//field.setBorder(...);
//return the custom field
return field;
}
//Method to get the current field contents if needed or if edited by the user
public List<JTextField> getCurrentFieldContent (){
return fieldList;
}
}
Related
I haven't been able to show a JTable inside a JPanel from dynamically generated data. I have even tried adding a layout manager so that I don't end up with a null layout manager and no table. Here is the code I'm using.
public void setReferencePanel(ArrayList<Item> items, String refFile) {
String[] columns = {"first", "last"};
String[][] data = {{"Adam", "Smith"}, {"Jon", "Bon Jovi"},{"John", "Doe"}};
JTable sample = new JTable(data, columns);
refListingPanel.add(sample);
refListingPanel.setBorder(BorderFactory.createTitledBorder("Reference File - " + refFile));
}
and earlier in the same file.
private JMenuBar menuBar;
private JPanel testListingPanel;
private JScrollPane testScroller;
private JPanel refListingPanel;
private JScrollPane refScroller;
private static Dimension listingDefault = new Dimension(350, 230);
private IDiffPresenter presenter;
private boolean allItems;
private boolean unChangedItems;
private boolean changedItems;
private JTable refTable;
private JTable testTable;
public MasterFrame (IDiffPresenter presenter) {
super("Magic Diff - Under Construction");
this.presenter = presenter;
menuBar = new JMenuBar();
setupFileMenu(presenter);
setupExportMenu(presenter);
setupDisplayChangedMenu();
setupAboutMenu();
setupReferencePanel();
setupTestPanel();
getContentPane().setLayout(new GridLayout(1,2));
setJMenuBar(menuBar);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize((int)listingDefault.getWidth() + 10, (int)listingDefault.getHeight() + 60);
Dimension DimMax = Toolkit.getDefaultToolkit().getScreenSize();
this.setMaximumSize(DimMax);
this.setExtendedState(JFrame.MAXIMIZED_BOTH);
...
}
private void setupReferencePanel() {
refListingPanel = new JPanel();
refListingPanel.setLayout(new BorderLayout());
refListingPanel.setBorder(BorderFactory.createTitledBorder("Reference File"));
refScroller = new JScrollPane(refListingPanel);
getContentPane().add(refScroller);
}
What am I missing or failing to do? I have even tried some sample data, what is currently in the code, and I get the same issue.
This is based on what cmickr and Andrew Thompson posted. I modified the following functions to work.
public void setReferencePanel(ArrayList<Item> items, String refFile) {
DefaultTableModel model = new DefaultTableModel(vectorize(items), makeHeaderVector());
refTable.setModel(model);
refListingPanel.setBorder(BorderFactory.createTitledBorder("Reference File - " + refFile));
}
private Vector vectorize(ArrayList<Item> items) {
Vector results = new Vector();
for (int i = 0; i < items.size(); i++) {
results.addElement(items.get(i).vectorize());
}
return results;
}
private Vector makeHeaderVector() {
String[] cols = { ... }; // hid application specific string array
Vector<String> results = new Vector<String>(Arrays.asList(cols));
return results;
}
This is my basic understanding of vectors, since I do not use them much. Also, this may not be the fastest way of approaching the problem, but my first goal is to get it working, then improve it. The important part was to use a TableModel, in my case DefaultTableModel, and then setModel() of the the JTable to the new model, like was referenced.
I created a button with JTextPane inside.
When I added JTextPane to the JButton I cant click on the button.
When I remove JTextPane I can click on the button.
Somebody know how to fix this problem?
public class BtnOrderFefcoStyle extends JButton {
private final static String NAME_FONT = "ARIAL";
private final static boolean IS_BOLD = true;
private final static int SIZE_FONT = 18;
private final static Color NAVY_COLOR = new Color(0 , 51 , 102)
private final static int BUTTON_WIDTH = 122;
private final static int BUTTON_HEIGHT = 64;
private final static int BORDER_THICKNESS = 2;
private int posX , posY;
public BtnOrderFefcoStyle(int pos_x , int pos_y)
{
super() ;
this.posX = pos_x;
this.posY= pos_y;
setOpaque(false);
setBorderPainted(false);
setContentAreaFilled(false);
setFocusable(false);
setEnabled(true);
setBorder(null);
setBounds(pos_x, pos_y, BUTTON_WIDTH, BUTTON_HEIGHT);
setForeground(Color.WHITE);
JTextPane nameBtn = new JTextPane();
nameBtn.setEditable(false);
nameBtn.setText("ADD TO LIST");
nameBtn.setAutoscrolls(true);
nameBtn.setEnabled(false);
nameBtn.setOpaque(false);
SimpleAttributeSet attribs = new SimpleAttributeSet();
StyleConstants.setAlignment(attribs, StyleConstants.ALIGN_CENTER);
StyleConstants.setFontFamily(attribs, NAME_FONT);
StyleConstants.setBold(attribs, IS_BOLD);
StyleConstants.setFontSize(attribs, SIZE_FONT);
nameBtn.setParagraphAttributes(attribs, true);
nameBtn.setCaretPosition(1);
nameBtn.setParagraphAttributes(attribs, true);
nameBtn.setDisabledTextColor(NAVY_COLOR);
//nameBtn.setBackground(new Color(153 , 153, 153));
nameBtn.setSize(BUTTON_WIDTH - 2 * BORDER_THICKNESS , BUTTON_HEIGHT - 2 * BORDER_THICKNESS);
//nameBtn.setForeground(NAVY_COLOR);
add(nameBtn);
}
#Override
protected void paintComponent(Graphics g)
{
// TODO Auto-generated method stub
super.paintComponent(g);
g.setColor(Color.WHITE);
g.fillRect(0 , 0 , BUTTON_WIDTH, BUTTON_HEIGHT);
g.setColor(Color.GRAY);
g.fillRect(BORDER_THICKNESS , BORDER_THICKNESS , BUTTON_WIDTH - 2 * BORDER_THICKNESS , BUTTON_HEIGHT - 2 * BORDER_THICKNESS );
}
}
What's happening in your current example is:
Your JTextPane is being placed on top of your JButton and as you removed the border from your JButton it's taking all the available space, so you're clicking over the JTextPane all the time.
If we add a border to the JTextPane this is what we get before removing the JButton's border and after
To fix this you can either:
Add a MouseListener to the JTextPane, for example:
nameBtn.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
super.mouseClicked(e);
System.out.println("Clicked on nameBtn");
}
});
create a method to use HTML as suggested in the comments above:
private String getButtonString(String stringFromFile) {
StringBuilder sb = new StringBuilder();
sb.append("<html><body><p>");
sb.append(stringFromFile);
sb.append("</p></body></html>");
return sb.toString();
}
This is how each of them look like when resized:
A MouseEvent is passed to the component that is clicked. If you add a JTextPane to the JButton, then you are clicking on the text pane, not the button.
You can tryd to remove the MouseListeners from the JTextPanel
for (MouseListener ml: textPane.getListeners(MouseListener.class))
textPane.removeMouseListener( ml );
Not sure if you also need to remove the MouseMotionListener.
I am a noob to java and I have hit a snag building my gui...What I need to do is run my shipmentApp program which displays my EnterShipInfo frame that has several text fields to enter data and an enter button that when clicked passes the entered data to my ShipmentFrame. Initially when the frame pops up there should be three labels that just say "label" in them and a display button, then when you click the display button it the data from the text fields pops up in the three labels along with some other words to make a phrase.
// ShipmentFrame code begins here
private static final long serialVersionUID = 1L;
private Label headerLbl = null;
private Button displayButton = null;
private Button Exit = null;
private Label shipLbl = null;
private Label empLbl = null;
private Label dateTimeLbl = null;
private Shipment s;
private Shipment sf;
public ShipmentFrame(Shipment ship){
super();
this.s = ship;
initialize();
s = ship;
}
public void actionPerformed(ActionEvent e) {
shipLbl.setText("Shipment number " + s.getShipmentNum() +
" was received from " + s.getSupplierName());
empLbl.setText("By employee number " + s.getEmployeeNum());
dateTimeLbl.setText("On " + s.getRevDate() + " at " + s.getRevTime());
}
// this is my code from EnterShipInfo
private static final long serialVersionUID = 1L;
private Label headerLbl = null;
private Button displayButton = null;
private Button Exit = null;
private Label dateLbl = null;
private Label timeLbl = null;
private Label suplLbl = null;
private Shipment s;
private Label shipNumLbl = null;
private Label empNumLbl = null;
private TextField empNumTF = null;
private TextField shipNumTF = null;
private TextField dateTF = null;
private TextField timeTF = null;
private TextField supplTF = null;
Shipment ship = new Shipment (" ", " ", " ", " ", " ");
// #jve:decl-index=0:
public EnterShipInfo(){
super();
// this.s = ship;
initialize();
}
// This is the part that was wrong
public void actionPerformed(ActionEvent e) {
String employeeNum = empNumTF.getText();
String shipmentNum = shipNumTF.getText();
String revDate = dateTF.getText();
String revTime = timeTF.getText();
String supplierName = supplTF.getText();
ShipmentFrame sf = new ShipmentFrame(null);
}
//Below is what I was looking for...maybe someone knows more efficient way to accomplish this though
public void actionPerformed(ActionEvent e) {
ship.setEmployeeNum(empNumTF.getText());
ship.setShipmentNum( shipNumTF.getText());
ship.setRevDate( dateTF.getText());
ship.setRevTime(timeTF.getText());
ship.setSupplierName( supplTF.getText());
ShipmentFrame sf = new ShipmentFrame(ship);
}
EDIT
So here's the general process for displaying a Component in a JFrame:
1 - Set up your JFrame (Layouts, borders, etc):
JFrame frame = new JFrame("Frame Title");
JPanel contentPane = ((JPanel) frame.getContentPane());
contentPane.setLayout(new GridLayout(4,1)); //use whatever kind of layout you need
contentPane.setBorder(new EmptyBorder(10,10,10,10)); //use whatever kind of border you need
2 - Initialize your Component(s) (in this case, two JTextFields and a JButton):
JTextField empNumTF = new JTextField("Initial text in field");
JTextField shipNumTF = new JTextField("Initial text in field");
JButton displayButton = new JButton("Display");
3 - Add your component(s) to the JFrame's contentPane:
contentPane.add(empNumTF);
contentPane.add(shipNumTF);
contentPane.add(displayButton);
4 - Pack and make visible:
frame.pack();
frame.setVisible(true);
Then your JFrame should be displayed with those Components.
ADDED
Now, if we want to manipulate what the user enters into those text fields, we need to add an action listener for the button. To do this:
1 - Make one of your classes an action listener (you can use the same class that the JButton is created in if you want) by stating that it implements ActionListener:
public class EnterShipInfo implements ActionListener{
2 - Add an action-listening object to the button like so:
displayButton.addActionListener(this);
//using "this" means that the object this JButton was created in is the action listener.
3 - Add an actionPerformed() method to your ActionListener (as it seems you have already done correctly):
public void actionPerformed(ActionEvent e){
//insert code to execute whenever your button is clicked.
}
So now, specifically to you, inside your actionPerformed() method, you probably want to handle it something like this:
public void actionPerformed(ActionEvent e){
if (e.getActionCommand().equals("Display")){ //"Display" is the text on the JButton
String employeeNum = empNumTF.getText();
String shipmentNum = shipNumTF.getText();
String revDate = dateTF.getText(); //These text fields
String revTime = timeTF.getText(); //not coded in
String supplierName = supplTF.getText(); //my example
ShipmentFrame sf = new ShipmentFrame(new Shipment(shipmentNum, supplierName, revDate, revTime, employeeNum)); //I'm just guessing at the order these come in
sf.setVisible(true);
}
}
Some key documentation you may want to take a look at:
javax.swing.JFrame
javax.swing.JPanel
javax.swing.JTextField
javax.swing.JButton
javax.swing.border.EmptyBorder
java.awt.GridLayout
I have a JTextArea inside a main layout that I want to update using a custom JDialog. Difficult to explain in words like this...so please just follow code and explanation process as outlined below:
I have a JPanel that contains the JTextArea (i.e. original JTextArea - 'cancellationPolicTA') that needs to be updated:
public class Panel_Other_Information extends JPanel {
private JTextArea cancellationPolicyTA, otherInformationTA;
public final String cancellationPolicyBorderTXT = " Cancellation Policy ";
public final String additionalInformationBorderTXT = " Other Information ";
public Panel_Other_Information () {
// Create and set up the window.
JPanel thisPanel = new JPanel ();
// [1] Define the Dimensions of the Panel.
Dimension panelSize = getPreferredSize();
panelSize.width = 520;
panelSize.height = 100;
setPreferredSize(panelSize);
setBorder(BorderFactory.createTitledBorder(" 15. Additional Information "));
// [2] Use the 'SpringLayout' to set or define the layout of components within this panel.
SpringLayout layout = new SpringLayout();
setLayout(layout);
setBackground(McGyver.APP_THEME_COLOR);
// [3] Define required Label components/controls.
JLabel cancellationPolicyLabel = new JLabel ("Cancellation Policy:");
JLabel otherInformationLabel = new JLabel ("Other Information:");
String canPolTxt = "No Cancellation Policy";
String othInfTxt = "No Additional Information";
// [4] Define required input (TextField) controls/components.
final int widthCB = 230;
final int heightCB = 48;
cancellationPolicyTA = new JTextArea(canPolTxt);
cancellationPolicyTA.setEditable(false);
cancellationPolicyTA.setWrapStyleWord(true);
cancellationPolicyTA.addMouseListener(new CancelPolicyMouseListener());
cancellationPolicyTA.addFocusListener(new CancelPolicyFocusListener());
otherInformationTA = new JTextArea(othInfTxt);
otherInformationTA.setEditable(false);
otherInformationTA.setWrapStyleWord(true);
otherInformationTA.addMouseListener(new OtherInformationMouseListener());
JScrollPane canPolTAScrollPane = new JScrollPane(cancellationPolicyTA);
canPolTAScrollPane.setPreferredSize(new Dimension(widthCB, heightCB));
JScrollPane otherInfoTAScrollPane = new JScrollPane(otherInformationTA);
otherInfoTAScrollPane.setPreferredSize(new Dimension(widthCB, heightCB));
// [5] Define button controls - if needed.
/* JButton saveDataBTN = new JButton("Save"); */
////////////////////////////////////////////////////////////////////////
// Define the layout of components - component-by-component //
////////////////////////////////////////////////////////////////////////
/* -- Component 1 - Additional Information - Cancellation Policy Label */
layout.putConstraint(SpringLayout.NORTH, cancellationPolicyLabel, 5, SpringLayout.NORTH, thisPanel);
layout.putConstraint(SpringLayout.WEST, cancellationPolicyLabel, 0, SpringLayout.EAST, thisPanel);
/* -- Component 2 - Additional Information - Cancellation Policy Text Area */
layout.putConstraint(SpringLayout.NORTH, canPolTAScrollPane, 5, SpringLayout.SOUTH, cancellationPolicyLabel);
layout.putConstraint(SpringLayout.WEST, canPolTAScrollPane, 0, SpringLayout.WEST, cancellationPolicyLabel);
/* -- Component 1 - Additional Information - Cancellation Policy Label */
layout.putConstraint(SpringLayout.NORTH, otherInformationLabel, 5, SpringLayout.NORTH, thisPanel);
layout.putConstraint(SpringLayout.WEST, otherInformationLabel, 30, SpringLayout.EAST, canPolTAScrollPane);
/* -- Component 2 - Additional Information - Cancellation Policy Text Area */
layout.putConstraint(SpringLayout.NORTH, otherInfoTAScrollPane, 5, SpringLayout.SOUTH, otherInformationLabel);
layout.putConstraint(SpringLayout.WEST, otherInfoTAScrollPane, 0, SpringLayout.WEST, otherInformationLabel);
// [4] Add Swing components to content pane.
add(cancellationPolicyLabel);
add(canPolTAScrollPane);
add(otherInformationLabel);
add(otherInfoTAScrollPane);
}
private class CancelPolicyMouseListener extends MouseAdapter {
public void mouseClicked(MouseEvent e){
if(e.getClickCount() == 1){
String cancelPolicyText = cancellationPolicyTA.getText();
if (cancelPolicyText.length() > 0) {
String dialogTitle = "15. Additional Information";
String borderTitle = cancellationPolicyBorderTXT;
McGyver.popCustomDialogTextAreaObject(dialogTitle, borderTitle, cancelPolicyText);
}
}
}
} }
Please take NOTE of the last bit of code above >> this is where the custom JDialog gets fired or called from.
I have the main class that runs the whole application:
public class Stan_App extends JFrame {
// [1] Instantiate all SWING components needed for this application.
public static Stan_App stanFrame;
private McGyver mcGyver = new McGyver();
public Panel_Other_Information additionalInformation = new Panel_Other_Information();
public Stan_App (String title) {
super(title);
// [1] Set LayoutManager
SpringLayout layout = new SpringLayout();
setLayout(layout);
setBackground(Color.CYAN);
////////////////////////////////////////////////////////////////////////
// [2] Define the layout of components - component-by-component //
////////////////////////////////////////////////////////////////////////
//-- Component 1 - JPanel - Additional Information --//
layout.putConstraint(SpringLayout.NORTH, additionalInformation, 17, SpringLayout.SOUTH, neighbourhoodRating);
layout.putConstraint(SpringLayout.WEST, additionalInformation, 20, SpringLayout.EAST, inRoomFacilities);
// [3] Add Swing components to content pane.
Container conTain = getContentPane();
conTain.add(additionalInformation);
}
public static void main (String[] args) {
SwingUtilities.invokeLater (new Runnable() {
#Override
public void run() {
createStanAppGUI();
}
});
}
private static void createStanAppGUI () {
// Override the default Font for the application.
McGyver.setUIFont(McGyver.APP_GLOBAL_FONT);
// This code chuck lays out the visual components (GUI) of the app.
stanFrame = new Stan_App (" S.T.A. Namibia - Database Manager " + " | THEME: " + McGyver.currentlySelectedAppThemeColor + " |");
// UIManager.getLookAndFeelDefaults().put("defaultFont", new Font("Noto Sans", Font.BOLD, 42));
stanFrame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
stanFrame.setSize(1925, 1050);
stanFrame.setResizable(false);
stanFrame.setVisible(true);
themeColorCB.setSelectedItem(McGyver.currentlySelectedAppThemeColor);
}
public void setCancellationTextFromCustomPopupDialog (String suppliedText) {
additionalInformation.setCancellation_Policy_TextArea_Value(suppliedText);
} }
I have a special helper class - where I keep all my useful code for implementation throughout the application:
public class McGyver {
public static JDialog custPopupDialog;
public static void popCustomDialogTextAreaObject (String dialogTitle, String borderTitle, String inputString) {
Panel_Custom_Dialog custDial = new Panel_Custom_Dialog(Stan_App.stanFrame, borderTitle, inputString);
final int widthCB = 500;
final int heightCB = 400;
custPopupDialog = new JDialog();
custPopupDialog.setTitle(dialogTitle);
custPopupDialog.add(custDial);
custPopupDialog.setSize(new Dimension(widthCB, heightCB)); /* Size(550, 450); */
custPopupDialog.setModal(true);
custPopupDialog.setLocationRelativeTo(null);
custPopupDialog.setVisible(true);
} }
Please NOTE: I have obviously cleaned up the code a lot to show only the important parts.
The Custom Dialog I need pulls all the current text from the JTextArea when the JTextArea is clicked on and then allows the user to continue editing the text inside another JTextArea in the custom JDialog (i.e. custPopupDialog). When the user clicks on the 'OKAY' button inside the custom JDialog the text from the custom dialog should be fed back to the original (i.e. cancellationPolicTA) JTextArea of the main class.
Everything works fine (i.e. data gets pulled into the custom JDialog and JDialog is displayed properly), but the text data is NOT handed back to the original JTextArea when the user clicks on the 'OKAY' button inside the custom JDialog. Please help. Thanks in advance.
I forgot to paste in the Custom JDialog code - (see below):
public class Panel_Custom_Dialog extends JPanel {
Stan_App stanAPP;
String borderHeaderString, editedCancellationPolicyTXT;
private JTextArea custDialogTA;
private Panel_Other_Information otherInfoPanel = new Panel_Other_Information();
public Panel_Custom_Dialog (Stan_App stanApp, String borderTitle, String inputMessageString) {
stanAPP = stanApp;
// Create and set up the window.
JPanel thisPanel = new JPanel();
borderHeaderString = null;
if (borderTitle == null) {
borderHeaderString = " Section Header Here! ";
} else {
borderHeaderString = borderTitle;
}
// [1] Define the Dimensions of the Panel.
Dimension panelSize = getPreferredSize();
panelSize.width = 500;
panelSize.height = 400;
setPreferredSize(panelSize);
setBorder(BorderFactory.createTitledBorder(borderHeaderString));
// [2] Use the 'SpringLayout' to set or define the layout of components within this panel.
SpringLayout layout = new SpringLayout();
setLayout(layout);
setBackground(McGyver.APP_THEME_COLOR);
// [3] Define the
final int widthCB = 450;
final int heightCB = 300;
// [4] Define the required components for this Panel.
custDialogTA = new JTextArea(inputMessageString);
custDialogTA.setBounds(5, 5, 0, 0);
custDialogTA.setLineWrap(true);
custDialogTA.setWrapStyleWord(true);
JScrollPane custDialogTextAreaScrollPane = new JScrollPane(custDialogTA);
custDialogTextAreaScrollPane.setPreferredSize(new Dimension(widthCB, heightCB));
// [3] Define the Button size fields.
final int widthBTN = 100;
final int heightBTN = 25;
JButton affirmativeBTN = new JButton(" OKAY "); affirmativeBTN.addActionListener(new CustomDialogAffirmationActionListener());
JButton cancellationBTN = new JButton(" CANCEL "); cancellationBTN.addActionListener(new CustomDialogCancellationActionListener());
affirmativeBTN.setPreferredSize(new Dimension(widthBTN, heightBTN));
cancellationBTN.setPreferredSize(new Dimension(widthBTN, heightBTN));
////////////////////////////////////////////////////////////////////////
// Define the layout of components - component-by-component //
////////////////////////////////////////////////////////////////////////
/* -- Component 1 - Additional Information - Custom Dialog TextArea */
layout.putConstraint(SpringLayout.NORTH, custDialogTextAreaScrollPane, 5, SpringLayout.NORTH, thisPanel);
layout.putConstraint(SpringLayout.WEST, custDialogTextAreaScrollPane, 0, SpringLayout.EAST, thisPanel);
/* -- Component 2 - Additional Information - Custom Dialog Affirmation Button */
layout.putConstraint(SpringLayout.NORTH, affirmativeBTN, 10, SpringLayout.SOUTH, custDialogTextAreaScrollPane);
layout.putConstraint(SpringLayout.WEST, affirmativeBTN, 0, SpringLayout.EAST, thisPanel);
/* -- Component 3 - Additional Information - Custom Dialog Cancellation Button */
layout.putConstraint(SpringLayout.NORTH, cancellationBTN, 0, SpringLayout.NORTH, affirmativeBTN);
layout.putConstraint(SpringLayout.WEST, cancellationBTN, 25, SpringLayout.EAST, affirmativeBTN);
// [5] Add the components defined above to the panel.
add(custDialogTextAreaScrollPane);
add(affirmativeBTN);
add(cancellationBTN);
}
public String getCust_Dialog_TextArea_Value () {
return custDialogTA.getText();
}
public void setCust_Dialog_TextArea_Value (String inputString) {
custDialogTA.setText(inputString);
}
private class CustomDialogAffirmationActionListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
if (borderHeaderString.equals(otherInfoPanel.cancellationPolicyBorderTXT)) {
editedCancellationPolicyTXT = custDialogTA.getText();
stanAPP.setCancellationTextFromCustomPopupDialog(editedCancellationPolicyTXT);
McGyver.custPopupDialog.dispose();
} else if (borderHeaderString.equals(otherInfoPanel.additionalInformationBorderTXT)) {
editedCancellationPolicyTXT = custDialogTA.getText();
stanAPP.setOtherInformationTextFromCustomPopupDialog(editedCancellationPolicyTXT);
McGyver.custPopupDialog.dispose();
}
}
}
private class CustomDialogCancellationActionListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
McGyver.custPopupDialog.dispose();
}
} }
See some of the code updated with comments,
First remove the stanAPP = new Stan_App(""); from the Panel_Custom_Dialog class and pass a reference to it, since it should have been instantiated else where,
McGyver.popCustomDialogTextAreaObject(dialogTitle, borderTitle, cancelPolicyText);
//* the popCustomDialog is Modal, this code above should block until the user hits ok or cancel,
String updatedText = McGyver.getInputString();
cancellationPolicyTA.setText(updatedText);
In the Mcgyver class and the popCustomDialogTExtAreaObject you need methods that will return the updated text. see the added method below with comments,
public class McGyver {
public static JDialog custPopupDialog;
public static Panel_Custom_Dialog custDial
public static void popCustomDialogTextAreaObject (String dialogTitle, String borderTitle, String inputString) {
custDial = new Panel_Custom_Dialog(borderTitle, inputString);
final int widthCB = 500;
final int heightCB = 400;
custPopupDialog = new JDialog();
custPopupDialog.setTitle(dialogTitle);
custPopupDialog.add(custDial);
custPopupDialog.setSize(new Dimension(widthCB, heightCB)); /* Size(550, 450); */
custPopupDialog.setModal(true);
custPopupDialog.setLocationRelativeTo(null);
custPopupDialog.setVisible(true);
}
//* add a method that will return the updated string.
//* for this to work, Panel_Custom_Dialog should have a method that will return the updated text
public static string getInputString()
{
return custDial.getInputString();
}
}
I have a Java program that contains multiple classes, all of which extend JPanel (except for the class containing the main method). I am trying to pass int variables from one class to another and, using some previously asked questions, came up with this:
Class RollPanel
public int getbrainCount()
{
return brainCount;
}
Class BrainsPanel (where I am trying to send the variable)
void setbrainCount()
{
RollPanel rollpanel = new RollPanel();
brainCount = rollpanel.getbrainCount();
}
This doesn't give any errors, but when I add brainCount to a label to see its value, it is always 0.
brainCount is declared at the class level of RollPanel, then given a value with this code which is in a button listener:
value1 = generator.nextInt(3) + 1;
value2 = generator.nextInt(3) + 1;
value3 = generator.nextInt(3) + 1;
//rollTotal++;
//Counts how many brains were rolled.
if (value1 == 1)
brainCount++;
if (value2 == 1)
brainCount++;
if (value3 == 1)
brainCount++;
I understand that just declaring a variable will automatically mean its value will be zero at first(which I assume is why it is displayed as zero), but how can I pass its updated value after the above code to brainsPanel so I can add its value to a label in brainsPanel? Would getBrainCount() come after the button listener? I feel like I'm overlooking something simple here...
EDIT:
I think the problem isn't with the setter as it is the getter. Since in RollPanel(where the getter is) I declare brainCount as an int its initial value is 0, so when the getter gets the value it always remains at 0 even though brainCount should be altered in the button listener. Here is RollPanel in its entirety. How can I make the getter get the updated value of brainCount instead of its initial 0?
package zombiedice;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
public class RollPanel extends JPanel
{
JLabel die1Label, die2Label, die3Label, testLabel;
JButton rollButton, sortButton;
JPanel dicePanel, buttonPanel;
ImageIcon die1, die2, die3;
int rollTotal, value1, value2, value3;
int brainCount, blastCount;
Random generator = new Random();
public RollPanel()
{
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
setBackground(Color.black);
dicePanel = new JPanel();
dicePanel.setBackground(Color.black);
//Creates blank ImageIcons to be used later to display dice.
die1 = new ImageIcon();
die2 = new ImageIcon();
die3 = new ImageIcon();
//A panel just to hold the buttons.
buttonPanel = new JPanel();
//Creates and links roll button to RollListener.
rollButton = new JButton("Roll");
rollButton.addActionListener(new RollListener());
buttonPanel.add(rollButton);
//After a roll, this button will need to be clicked so brain and blast
//die can be sorted into their proper catergories.
sortButton = new JButton("Sort");
sortButton.addActionListener(new SortListener());
//Creates labels out of the dice images.
die1Label = new JLabel(die1);
die2Label = new JLabel(die2);
die3Label = new JLabel(die3);
//Adds image labels to the panel that holds the dice.
dicePanel.add(die1Label);
dicePanel.add(die2Label);
dicePanel.add(die3Label);
add(dicePanel);
add(buttonPanel);
} //Closes constructor
//Roll button listener.
private class RollListener implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
rollButton.setEnabled(false);
repaint();
buttonPanel.add(sortButton);
repaint();
sortButton.setEnabled(true);
repaint();
value1 = generator.nextInt(3) + 1;
value2 = generator.nextInt(3) + 1;
value3 = generator.nextInt(3) + 1;
//rollTotal++;
//Counts how many brains were rolled.
if (value1 == 1)
brainCount++;
if (value2 == 1)
brainCount++;
if (value3 == 1)
brainCount++;
//Updates the dice
die1Label.setIcon(new ImageIcon(value1 + ".png"));
die2Label.setIcon(new ImageIcon(value2 + ".png"));
die3Label.setIcon(new ImageIcon(value3 + ".png"));
} //Closes actionPerformed
} //Closes the listener for the roll button
//Sort button listener.
private class SortListener implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
sortButton.setEnabled(false);
repaint();
rollButton.setEnabled(true);
repaint();
} //Closes actionPerformed.
}//Closes sort button listener.
public int getBrainCount()
{
return brainCount;
}
} //Closes class
BrainsPanel
package zombiedice;
import javax.swing.*;
import java.awt.*;
public class BrainsPanel extends JPanel
{
ImageIcon icon1 = new ImageIcon();
ImageIcon icon2 = new ImageIcon();
JLabel brainTotal, label1, label2;
JPanel brainPanel;
int brainCount;
void setbrainCount(int count)
{
// RollPanel rollpanel = new RollPanel();
brainCount = count;
//brainCount = count;
}
public BrainsPanel()
{
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
setBackground(Color.black);
icon1 = new ImageIcon("1.png");
icon2 = new ImageIcon("1.png");
label1 = new JLabel(icon1);
label2 = new JLabel(icon2);
brainTotal = new JLabel ("Brains eaten: " + brainCount);
add(label1);
add(label2);
add(brainTotal);
} //Closes constructor
} //Closes class
In this peace of code:
void setbrainCount() {
RollPanel rollpanel = new RollPanel();
brainCount = rollpanel.getbrainCount();
}
You always create a new RollPanel object before getting brainCount. Of course it is 0 if it is declared as field in RollPanel. The variable was newly initialized with the object creation just the line before.
You should make sure you always use the same RollPanel object, e.g. keep it as field in BrainsPanel. It's hard to say for sure with the given code.
I believe you should try the following:
void setbrainCount(RollPanel rollPanel)
{
brainCount = rollpanel.getbrainCount();
}
This way you won't try to use the newly initialized value which is always 0.
Althozuh technically, it would make more sense to just send the count over and set that
void setbrainCount(int brainCount)
{
this.brainCount = brainCount;
}