Whe does button not work after adding JTextPane? - java

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.

Related

Why does JLabel convert any nuber in a string to "..." in Java? [duplicate]

On most systems, the content in my JLabel just shows fine. It is also resided in a way that it should be always big enough to show its content text because I basically do this:
label.setText(text);
label.setFont(new Font(fontName, 0, 12));
int width = label.getFontMetrics(label.getFont()).stringWidth(text);
int height = 21; // this should always be enough
label.setBounds(new Rectangle(x, y, width, height));
But on some systems (not my own so I cannot really debug it that easy), it cuts the text and shows "..." at the end.
You can see the full code here and you can see the example here (Abbildungen_Bijektiv_X3).
I also have some similar case for JButton.
How can I force Swing to not do that? (Even if it thinks that the component is too small.)
Where exactly does Swing handle this? I browsed through the code of JButton and some related classes but I didn't really found the code where it cuts the text and adds the ellipsis.
There should be no need to set the bounds of the label.
That is the job of a layout manager. Learn to use layout managers and you won't have this problem.
Edit:
Layout managers use:
label.setSize( label.getPreferredSize() );
I am doing this now (for buttons but you could do it in a similar way for other controls):
static public class ButtonUI extends MetalButtonUI {
public static ComponentUI createUI(JComponent c) {
return new ButtonUI();
}
#Override public void paint(Graphics g, JComponent c) {
JSimpleLabel.activateAntiAliasing(g);
AbstractButton b = (AbstractButton) c;
ButtonModel model = b.getModel();
String text = b.getText();
clearTextShiftOffset();
// perform UI specific press action, e.g. Windows L&F shifts text
if (model.isArmed() && model.isPressed()) {
paintButtonPressed(g,b);
}
FontMetrics metrics = g.getFontMetrics();
Rectangle2D stringBounds = metrics.getStringBounds(text, g);
g.drawString(text,
(b.getWidth() - (int)stringBounds.getWidth()) / 2,
metrics.getLeading() + metrics.getMaxAscent() + (b.getHeight() - (int)stringBounds.getHeight()) / 2);
if (b.isFocusPainted() && b.hasFocus()) {
Rectangle viewRect = new Rectangle();
final int inset = 1;
viewRect.x = inset;
viewRect.y = inset;
viewRect.width = b.getWidth() - (inset + viewRect.x) - 1;
viewRect.height = b.getHeight() - (inset + viewRect.y) - 1;
g.setColor(getFocusColor());
g.drawRect(viewRect.x, viewRect.y, viewRect.width, viewRect.height);
}
}
}
public void init() {
try {
UIManager.setLookAndFeel(new javax.swing.plaf.metal.MetalLookAndFeel() {
private static final long serialVersionUID = 1L;
#Override public UIDefaults getDefaults() {
UIDefaults table = super.getDefaults();
table.put("ButtonUI", ButtonUI.class.getName());
return table;
}
});
} catch (Exception e) {
e.printStackTrace();
}
// ...
}
You could use a cross platform look and feel (Like Nimbus) to stop this occuring

How to reuse a common panel?

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;
}
}

Using paintComponent() on a JFrame canvas being altered by a separate GUI

I am trying to make a JComponent application which uses two JFrames, one frame with alterable sliders and textfields for the graphical display of a firework on the second. When the "fire" button is pressed, a rendering of the firework should appear. However, I have found through placing strategic print statements, that my paintComponent() method does not run even though the conditional statement wrapping the code is satisfied. I have also double checked all of my other methods to ensure that correct values are generated at the correct times. After looking through all of the JComponent literature and questions I could find, I'm afraid I cannot get it to work - this problem is most likely derived from my lack of familiarity with the library. That being said, any advice no matter how rudimentary, will be much appreciated. Abridged code is below:
*The swing timer may also be the issue for I am not sure if I have used it correctly
[fireworksCanvas.java]
public class fireworkCanvas extends JComponent implements ActionListener{
private static final long serialVersionUID = 1L;
private ArrayList<Ellipse2D> nodes = new ArrayList<Ellipse2D>();
private ArrayList<Line2D> cNodes = new ArrayList<Line2D>();
private ArrayList<QuadCurve2D> bCurves = new ArrayList<QuadCurve2D>();
private int[] arcX;
private int[] arcY;
private Color userColor;
private Random rand = new Random();
private int shellX, shellY, fType, theta, velocity;
private Timer timer;
private int time;
private double g = -9.8; //gravity in m/s
public boolean explosivesSet;
public fireworkCanvas() {
time = rand.nextInt(3000) + 2000;
timer = new Timer(time, this); // 5 seconds
timer.start();
fType = 0;
}
#Override
public void paintComponent(Graphics g){
if (explosivesSet) {
System.out.println("fType" + fType);
super.paintComponent(g);
Graphics2D g2D = (Graphics2D) g;
g.setColor(Color.BLACK);
g.drawPolyline(arcX, arcY, arcX.length);
for (Ellipse2D e : nodes) {
System.out.println("painting nodes"); // NEVER PRINTS
g.setColor(userColor);
g.fillOval(shellX + (int) e.getX(), shellY + (int) e.getY(), (int) e.getWidth(), (int) e.getHeight());
}
for (Line2D l: cNodes) {
System.out.println("painting cNodes"); // NEVER PRINTS
g.setColor(determineColor("l"));
g.drawLine(shellX + (int) l.getX1(), shellY + (int) l.getY1(), shellX + (int) l.getX2(), shellY + (int) l.getY2());
}
for (QuadCurve2D c: bCurves) {
System.out.println("painting curves"); // NEVER PRINTS
g.setColor(determineColor("c"));
g2D.draw(c);
}
}
}
public Color determineColor(String type) {
// returns color
}
public void setExplosives() {
if (fType != 5 && fType != 0) {
nodes.clear(); // clears three array lists with FW components
cNodes.clear(); // these are the components to paint for the
bCurves.clear(); // firework explosion graphic
setArc(); // stores path of shell for a polyLine to be drawn
// builds and generates components for FW based on type chosen (fType)
setExplosivesSet(true);
repaint();
}
}
public void setArc() {
// builds int[] for shellX, shellY
}
#Override
public void actionPerformed(ActionEvent e) {
// nothing is here??
// should I use the action performed in some way?
}
[GUI.java]
public class GUI extends JFrame implements ActionListener, ChangeListener, ItemListener, MouseListener{
private static JFrame canvasFrame = new JFrame("Canvas");
private fireworkCanvas canvas = new fireworkCanvas();
private Choice fireworkChooser = new Choice();
private JSlider launchAngle = new JSlider();
private JSlider velocity = new JSlider();
private JSlider r = new JSlider();
private JSlider g = new JSlider();
private JSlider b = new JSlider();
private JPanel panel = new JPanel();
private JButton button = new JButton("Fire!");
private JLabel launchLabel = new JLabel("Launch Angle ");
private JLabel velocityLabel = new JLabel("Velocity ");
private JLabel rLabel = new JLabel("Red ");
private JLabel gLabel = new JLabel("Green ");
private JLabel bLabel = new JLabel("Blue ");
public static int fHeight = 500;
public static int fWidth = 500;
public GUI() {
this.add(panel);
panel.add(button);
panel.add(fireworkChooser);
panel.add(launchAngle);
panel.add(launchLabel);
panel.add(velocity);
panel.add(velocityLabel);
panel.add(r);
panel.add(rLabel);
panel.add(g);
panel.add(gLabel);
panel.add(b);
panel.add(bLabel);
addActionListener(this);
BoxLayout bl = new BoxLayout(getContentPane(), BoxLayout.Y_AXIS);
setLayout(bl);
fireworkChooser.addItemListener(this);
launchAngle.addChangeListener(this);
velocity.addChangeListener(this);
r.addChangeListener(this);
g.addChangeListener(this);
b.addChangeListener(this);
button.addActionListener(this);
fireworkChooser.add("Firework 1");
fireworkChooser.add("Firework 2");
fireworkChooser.add("Firework 3");
fireworkChooser.add("Firework 4");
fireworkChooser.add("Super Firework");
launchAngle.setMinimum(1);
launchAngle.setMaximum(90);
velocity.setMinimum(1);
velocity.setMaximum(50);
r.setMinimum(0);
r.setMaximum(255);
g.setMinimum(0);
g.setMaximum(255);
b.setMinimum(0);
b.setMaximum(255);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(600, 200);
}
#Override
public void stateChanged(ChangeEvent e) {
// sets FW variables
}
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == button) {
canvas.setfType(fireworkChooser.getSelectedIndex()+1);
canvas.setExplosives();
canvas.repaint();
canvas.setExplosivesSet(false);
System.out.println("button fired");
}
}
public static void createAndShowGUI() {
GUI gui = new GUI();
gui.pack();
gui.setLocationRelativeTo(null);
gui.setVisible(true);
gui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
fireworkCanvas canvas = new fireworkCanvas();
canvasFrame.pack();
canvasFrame.add(canvas);
canvasFrame.setLocationRelativeTo(null);
canvasFrame.setVisible(true);
canvasFrame.setSize(fWidth, fHeight);
canvasFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
First of all:
public fireworkCanvas()
Class names should start with an upper case character. All the other classes in your code follow this rule. Learn by example.
private Choice fireworkChooser = new Choice();
Choice is an AWT component don't mix AWT components in a Swing application. Use a JComboBox.
that my paintComponent() method does not run
fireworkCanvas canvas = new fireworkCanvas();
canvasFrame.pack();
canvasFrame.add(canvas);
You add the canvas to the frame AFTER you pack() the frame, so the size of the canvas is (0, 0) and there is nothing to paint.
The canvas should be added to the frame BEFORE the pack() and you should implement getPreferredSize() in your FireworkCanvas class so the pack() method can work properly.
Read the section from the Swing tutorial on Custom Painting for the basics and working examples to get you started.

Update JTextArea text in JFrame from Custom JDialog output data or results

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();
}
}

Simple ActionListener within a 2D array of JButtons

Okay so I am making a 2d array of JToggleButtons. I got the action listener up and going, but I have no way to tell which button is which.
If I click one, all it returns is something like
javax.swing.JToggleButton[,59,58,19x14,alignmentX=0.0,alignmentY=0.5,border=javax.swing.plaf.BorderUIResource$CompoundBorderUIResource#53343ed0,flags=296,maximumSize=,minimumSize=,preferredSize=,defaultIcon=,disabledIcon=,disabledSelectedIcon=,margin=javax.swing.plaf.InsetsUIResource[top=2,left=14,bottom=2,right=14],paintBorder=true,paintFocus=true,pressedIcon=,rolloverEnabled=false,rolloverIcon=,rolloverSelectedIcon=,selectedIcon=,text=]
Is there anyway to stick some sort of item or number in the button object to associate each button?
And then when the button is clicked I can retrieve that item or number that was given to it?
Here is my button generator code. (How could I make "int l" associate (and count) to each button made, when it is called, it will return that number, or something along those lines.
JToggleButton buttons[][] = new JToggleButton[row][col];
int l = 0;
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
buttons[i][j] = new JToggleButton("");
buttons[i][j].setSize(15,15);
buttons[i][j].addActionListener(new e());
panel.add(buttons[i][j]);
l++;
}
}
ActionListner
public class e implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
System.out.println(source);
}
}
variable "source" is what I use to get my data, so how can int l, be returned through "source" (as its unique value for the unique button clicked) as a button is clicked?
Thanks,
-Austin
very simple way is add ClientProperty to the JComponent, add to your definition into loop e.g.
buttons[i][j].putClientProperty("column", i);
buttons[i][j].putClientProperty("row", j);
buttons[i][j].addActionListener(new MyActionListener());
rename e to the MyActionListener and change its contents
public class MyActionListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
JToggleButton btn = (JToggleButton) e.getSource();
System.out.println("clicked column " + btn.getClientProperty("column")
+ ", row " + btn.getClientProperty("row"));
}
EDIT:
for MinerCraft clone isn't required to implements ony of Listeners, there is only about Icon, find out that in this code (don't implement any of Listeners anf remove used ItemListener)
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ButtonsIcon extends JFrame {
private static final long serialVersionUID = 1L;
private Icon errorIcon = UIManager.getIcon("OptionPane.errorIcon");
private Icon infoIcon = UIManager.getIcon("OptionPane.informationIcon");
private Icon warnIcon = UIManager.getIcon("OptionPane.warningIcon");
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
ButtonsIcon t = new ButtonsIcon();
}
});
}
public ButtonsIcon() {
setLayout(new GridLayout(2, 2, 4, 4));
JButton button = new JButton();
button.setBorderPainted(false);
button.setBorder(null);
button.setFocusable(false);
button.setMargin(new Insets(0, 0, 0, 0));
button.setContentAreaFilled(false);
button.setIcon((errorIcon));
button.setRolloverIcon((infoIcon));
button.setPressedIcon(warnIcon);
button.setDisabledIcon(warnIcon);
add(button);
JButton button1 = new JButton();
button1.setBorderPainted(false);
button1.setBorder(null);
button1.setFocusable(false);
button1.setMargin(new Insets(0, 0, 0, 0));
button1.setContentAreaFilled(false);
button1.setIcon((errorIcon));
button1.setRolloverIcon((infoIcon));
button1.setPressedIcon(warnIcon);
button1.setDisabledIcon(warnIcon);
add(button1);
button1.setEnabled(false);
final JToggleButton toggleButton = new JToggleButton();
toggleButton.setIcon((errorIcon));
toggleButton.setRolloverIcon((infoIcon));
toggleButton.setPressedIcon(warnIcon);
toggleButton.setDisabledIcon(warnIcon);
toggleButton.addItemListener(new ItemListener() {
#Override
public void itemStateChanged(ItemEvent e) {
if (toggleButton.isSelected()) {
} else {
}
}
});
add(toggleButton);
final JToggleButton toggleButton1 = new JToggleButton();
toggleButton1.setIcon((errorIcon));
toggleButton1.setRolloverIcon((infoIcon));
toggleButton1.setPressedIcon(warnIcon);
toggleButton1.setDisabledIcon(warnIcon);
toggleButton1.addItemListener(new ItemListener() {
#Override
public void itemStateChanged(ItemEvent e) {
if (toggleButton1.isSelected()) {
} else {
}
}
});
add(toggleButton1);
toggleButton1.setEnabled(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setVisible(true);
}
}
Just add the row and column data to each listener. You could add an explicit constructor, but I suggest adding a little method (which may have more added to it later).
buttons[i][j].addActionListener(e(i, j));
...
private ActionListener e(final int i, final int j) {
return new ActionListener() {
// i and j available here
...
(In JDK8 you should be able to use a lambda to reduce the syntax clutter.)
And then renaming it with a better name.
I made a minesweeper game and ran into a similar problem. One of the only ways you can do it, is to get the absolute location of the clicked button, then divide that by the x and y between buttons, so for me it was
if ((e.getComponent().getX() != (randx) * 25 && e.getComponent().getY() != (randy) * 25) &&bomb[randx][randy] == false) {
This code was to check if the area had bombs. So I had 25 x and y difference between location of bombs. That will just give you a general idea on how to do this.
I believe: (x - x spacing on left side) / buffer - 1 would work.
Instead of 'e.getSource()' you can always call 'e.getActionCommand()'. For each button you can specify this by:
JButton button = new JButton("Specify your parameters here"); /*you get these from getActionCommand*/
button.setText("title here"); /*as far as I remember*/

Categories

Resources