Please have a look at the following code
Main.Java
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
public class Main extends JFrame
{
private JButton ok;
public Main()
{
ok = new JButton("OK");
ok.addActionListener(new ButtonAction());
JPanel panel = new JPanel();
panel.setLayout(new FlowLayout());
panel.add(ok);
getContentPane().add(panel,"South");
this.setVisible(true);
this.setSize(new Dimension(200,200));
this.validate();
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[]args)
{
try
{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
new Main();
}
catch(Exception e)
{
}
}
private class ButtonAction implements ActionListener
{
public void actionPerformed(ActionEvent ae)
{
Dialog d = new Dialog();
d.setVisible(true);
}
}
}
Dialog.java
import java.awt.Event;
import java.awt.*;
import javax.swing.*;
public class Dialog extends JDialog
{
private JButton done;
public Dialog()
{
done = new JButton("Done");
this.add(done);
this.setSize(new Dimension(400,200));
}
}
In here, I want to "attach" the Dialog form to the main form. Which means, when I click the OK button in Main.Java, Dialog form will get attached to the right side of the main form. So, when I move the main form, the dialog also get moved. However, dialog form should be independent, which means, when I click "x" button in dialog form, only that form exists, not the main form.
How can I attach this dialog form, to the right side of the main form, when the button is clicked? Please help!
The answer is not MouseListener, but it is ComponentListener. I managed to do it with using that listener's "componentMoved()" method.
Main.java
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
public class Main extends JFrame implements ComponentListener, ActionListener
{
private JButton ok;
private Dialog dialog;
public Main()
{
ok = new JButton("OK");
ok.addActionListener(this);
dialog = new Dialog();
JPanel panel = new JPanel();
panel.setLayout(new FlowLayout());
panel.add(ok);
getContentPane().add(panel,"South");
this.addComponentListener(this);
this.setVisible(true);
this.setSize(new Dimension(200,200));
this.validate();
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[]args)
{
try
{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
new Main();
}
catch(Exception e){}
}
public void actionPerformed(ActionEvent ae)
{
dialog.setVisible(true);
}
#Override
public void componentHidden(ComponentEvent arg0) {}
#Override
public void componentMoved(ComponentEvent arg0)
{
int x = this.getX() + this.getWidth();
int y = this.getY();
dialog.setDialogLocation(x, y);
}
#Override
public void componentResized(ComponentEvent arg0) {}
#Override
public void componentShown(ComponentEvent arg0) {}
}
Dialog.java
import java.awt.Dimension;
import javax.swing.JButton;
import javax.swing.JDialog;
public class Dialog extends JDialog
{
private JButton done;
public Dialog()
{
done = new JButton("Done");
this.add(done);
this.setSize(new Dimension(400,200));
}
public void setDialogLocation(int x, int y)
{
this.setLocation(x, y);
}
}
I'm not aware of any built-in function that you can just say "dialog.moveWithThisOtherWindow(otherWindow)" or some such and it just happens. You would have to write code to do this yourself.
Create a mouse listener or mouse adapter on the parent form. In the "mouse moved" event in the mouse listener, move the child form. Of course the parent would have to have a handle to the child. Depending how you create the windows, you may need some sort of "register" function that the child can call to identify himself to the parent.
Related
Say I have a separate class that has a void method called sampleVoidMethod that asks and prints user input.
I have assigned a JButton in another class to initiate sampleVoidMethod(). What I don't understand is how to make the sampleVoidMethod display its output inside the JFrame.
Right now, it's displaying sampleVoidMethod body on my IDE's console with the JFrame open. Below is the jframe class:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class someGUIClass {
public void createWindow() {
JFrame battleFrame = new JFrame("Welcome");
battleFrame.setVisible(true);
battleFrame.setResizable(true);
battleFrame.setDefaultCloseOperation((JFrame.EXIT_ON_CLOSE));
battleFrame.setSize(600,500);
battleFrame.setLocationRelativeTo(null);
JPanel panel = new JPanel();
battleFrame.add(panel);
JButton buttonOne = new JButton("Press Me");
buttonOne.addActionListener((new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
sampleVoidMethod();
}
}));
buttonOne.setVisible(true);
buttonOne.setBounds(400,300,100,100);
panel.add(buttonOne);
}
}
Below is the sampleVoidMethod of SomeClass:
public void sampleVoidMethod() {
System.out.println("I am a sample method!");
}
I didn't really know how else to phrase that but essentially:
-I have a few separate "pieces" that I am trying to add onto a master frame; to keep the code from getting unwieldy I have each "piece" be its own class.
-I'm getting stuck on adding the panells onto the master frame, because the classes themselves aren't panels, rather the method of the class creates the panel, which creates issues that I don't know how to solve.
PIECE (works on its own when I have it make a dialog instead of be a panel):
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class PieceThing3 extends JPanel //<switched from JDialog
{
//set up variables here
private ActionListener pieceAction = new ActionListener()
{
public void actionPerformed (ActionEvent ae)
{
// Action Listener (this also works)
}
};
private void createPiece()
{
//setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
//setLocationByPlatform(true);
// the above are commented out when I switch from dialog to panel
JPanel contentPane = new JPanel();
//something that uses pieceAction is here
//two buttons, b and s, with action listeners are here
contentPane.add(b);
contentPane.add(s);
add(contentPane);
//pack();
//again, commented out to switch from dialog
setVisible(true);
System.out.println("hi I'm done");
//just to check and make sure it's done
}
public static void main(String[] args)
{
// TODO Auto-generated method stub
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new PieceThing3().createPiece();
}
});
}
}
Sorry that is very vague, but the intricacies are not as important as the general idea - it works perfectly when I have it create its own dialog box, but now I am trying to get it to make a panel within a master code, below:
MASTER:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class CollectGUI extends JFrame{
private void createDialog(){
this.setSize(2000,1000);
this.setLocation(0,0);
this.setTitle("TITLE");
PieceThing3 pt = new PieceThing3();
//HERE, if I do pt.main(null); while it is in "dialog mode" (rather than panel) it pops up a dialog box and everything is hunky dory. But I don't know how to get it to add the method as a panel.
this.add(pt.main(null));
//this gives an error
this.setVisible(true);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
new CollectGUI().createDialog();
}
}
As I said in the comments, if I just do pt.main(null) when pt is set to make a dialog, it does it, but if I try to add pt.main(null) as a panel it throws an error. Can anybody give me some insight on how to add a method of a class rather than a class? I'm pretty stumped.
THANK YOU!!
You are definitely on the right track working to maintain separation of concerns and implement your gui in a number of distinct components. Try something like this:
Panel1
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Panel1 extends JPanel {
public Panel1() {
this.add(new JLabel("This is panel 1"));
}
}
Panel2
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Panel2 extends JPanel {
public Panel2() {
this.add(new JLabel("This is panel 2"));
}
}
JFrame
import java.awt.BorderLayout;
import javax.swing.JFrame;
import org.yaorma.example.jframe.panel.panel1.Panel1;
import org.yaorma.example.jframe.panel.panel2.Panel2;
public class ExampleJFrame extends JFrame {
public ExampleJFrame() {
super("Example JFrame Application");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(400,400);
this.setLayout(new BorderLayout());
Panel1 pan1 = new Panel1();
Panel2 pan2 = new Panel2();
this.add(pan1, BorderLayout.NORTH);
this.add(pan2, BorderLayout.SOUTH);
this.setVisible(true);
}
}
main:
public class ExampleApplication {
public static void main(String[] args) throws Exception {
new ExampleJFrame();
}
}
EDIT:
Here's a Panel1 with a little more content.
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import org.yaorma.example.action.sayhello.SayHelloAction;
public class Panel1 extends JPanel {
//
// instance variables
//
private JButton pressMeButton;
//
// constructor
//
public Panel1() {
this.setLayout(new BorderLayout());
this.add(new JLabel("This is panel 1"), BorderLayout.NORTH);
this.initPressMeButton();
}
//
// button
//
private void initPressMeButton() {
this.pressMeButton = new JButton("Press Me");
this.pressMeButton.addActionListener(new PressMeButtonActionListener());
this.add(pressMeButton, BorderLayout.SOUTH);
}
//
// method to get the parent jframe
//
private JFrame getParentJFrame() {
Container con = this;
while(con != null) {
con = con.getParent();
if(con instanceof JFrame) {
return (JFrame)con;
}
}
return null;
}
//
// action listener for Press Me button
//
private class PressMeButtonActionListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
JFrame jFrame = getParentJFrame();
SayHelloAction action = new SayHelloAction(jFrame);
action.execute();
}
}
}
Action called by button:
import javax.swing.JFrame;
import javax.swing.JOptionPane;
public class SayHelloAction {
private JFrame owner;
public SayHelloAction(JFrame owner) {
this.owner = owner;
}
public void execute() {
JOptionPane.showMessageDialog(owner, "Hello World");
}
}
My problem is the following: In my application the user clicks a button which brings up a dialog box (a custom jOptionPane). This dialog contains a JTextArea in which the user will type a response, which will then be processed by the application, however I would like this JTextArea (which will hold the user's input and currently contains example text like "Write your answer here") to be automatically highlighted.
I can do this normally, by calling requestFocusInWindow() followed by selectAll() on the JTextArea however there seems to be a problem when this is done using a JOptionPane which I'm guessing is to do with the fact that the focus cannot shift to the JTextArea successfully.
I've made a SSCCE to demonstrate this clearly, and hopefully get an answer from one of you guys as to how I can make this possible. Thanks in advance!
Class 1/2 : Main
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
public class Main extends JFrame{
public static void main(String[] args) {
Main main = new Main();
main.go();
}
private void go() {
JPanel background = new JPanel();
JPanel mainPanel = new ExtraPanel();
((ExtraPanel) mainPanel).setupPanel();
JButton testButton = new JButton("Test the jOptionPane");
testButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
optionPaneTest();
}
});
background.add(mainPanel);
background.add(testButton);
getContentPane().add(background);
pack();
setVisible(true);
}
private void optionPaneTest() {
JPanel testPanel = new ExtraPanel();
((ExtraPanel) testPanel).setupPanel();
int result = JOptionPane.showConfirmDialog(null, testPanel,
"This is a test", JOptionPane.OK_CANCEL_OPTION);
}
}
----------------------------------------------------------------------------- Class 2/2 : ExtraPanel
import javax.swing.JPanel;
import javax.swing.JTextArea;
public class ExtraPanel extends JPanel{
public void setupPanel() {
JTextArea textArea = new JTextArea();
textArea.setText("Write your response here");
textArea.requestFocusInWindow();
textArea.selectAll();
add(textArea);
}
}
Just add
textArea.getCaret().setSelectionVisible(true)
After textArea.selectAll();
If you want focus in the TextArea so that the user can immediately start typing, you can trigger the selection using the ancestor added event.
public void setupPanel() {
final JTextArea textArea = new JTextArea();
textArea.setText("Write your response here");
textArea.addAncestorListener(new AncestorListener() {
public void ancestorRemoved(AncestorEvent event) { }
public void ancestorMoved(AncestorEvent event) { }
public void ancestorAdded(AncestorEvent event) {
if (event.getSource() == textArea) {
textArea.selectAll();
textArea.requestFocusInWindow();
}
}
});
add(textArea);
}
So I've built a very basic Web browser - I'm trying desperately to remove the contents of the address bar when a user clicks on it (JTextField) this appears with some text in as default. Any advice is appreciated.
Have a great day!
MY CODE
import java.awt.*;
import java.awt.event.*;
import java.io.IOException;
import javax.swing.*;
import javax.swing.event.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class Web_Browser extends JFrame {
private final JTextField addressBar;
private final JEditorPane display;
// Constructor
public Web_Browser() {
super("Web Browser");
addressBar = new JTextField("Click & Type Web Address e.g. http://www.google.com");
addressBar.addActionListener(
new ActionListener() {
#Override
public void actionPerformed(ActionEvent event) {
loadGo(event.getActionCommand());
}
}
);
add(addressBar, BorderLayout.NORTH);
display = new JEditorPane();
display.setEditable(false);
display.addHyperlinkListener(
new HyperlinkListener(){
#Override
public void hyperlinkUpdate(HyperlinkEvent event){
if(event.getEventType()==HyperlinkEvent.EventType.ACTIVATED){
loadGo(event.getURL().toString());
}
}
}
);
add(new JScrollPane(display), BorderLayout.CENTER);
setSize(500,300);
setVisible(true);
}
// loadGo to sisplay on the screen
private void loadGo(String userText) {
try{
display.setPage(userText);
addressBar.setText(userText);
}catch(IOException e){
System.out.println("Invalid URL, try again");
}
}
}
Use a FocusListener. On focusGained, select all.
addressBar.addFocusListener(new FocusAdapter() {
#Override
public void focusGained(FocusEvent e) {
JTextComponent textComponent = (JTextComponent) e.getSource();
textComponent.selectAll();
}
});
For example:
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import javax.swing.*;
import javax.swing.text.JTextComponent;
#SuppressWarnings("serial")
public class FocusExample extends JPanel {
private static final int TF_COUNT = 5;
private JTextField[] textFields = new JTextField[TF_COUNT];
public FocusExample() {
for (int i = 0; i < textFields.length; i++) {
textFields[i] = new JTextField("Foo " + (i + 1), 10);
textFields[i].addFocusListener(new FocusAdapter() {
#Override
public void focusGained(FocusEvent e) {
JTextComponent textComponent = (JTextComponent) e.getSource();
textComponent.selectAll();
}
});
add(textFields[i]);
}
}
private static void createAndShowGui() {
FocusExample mainPanel = new FocusExample();
JFrame frame = new JFrame("FocusExample");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
This gives the user the option of leaving the previous text in place, of adding to the previous text, or of simply over-writing it by typing.
new JTextField("Click & Type Web Address e.g. http://www.google.com");
Maybe you want the Text Prompt, which doesn't actually store any text in the text field. It just gives the user a hint what the text field is for.
This is beneficial so that you don't generate DocumentEvents etc., since you are not actually changing the Document.
Add a mouseListener instead of your actionListener method.
addressBar.addMouseListener(new MouseAdapter(){
#Override
public void mouseClicked(MouseEvent e){
addressBar.setText("");
}
How can I assign two buttons to share the same class for handling events in Java/swing?
For example, I have this:
private class BtnEvtHandler implements ActionListener {
private int counter=10;
public void actionPerformed(ActionEvent e) {
gs.setX(counter);
gs.repaint();
counter=counter+10;
}
public void actionPerformed(ActionEvent e) {
//action for move button
}
}
JButton jumpBtn= new JButton("JUMP");
BtnEvtHandler okButtonHandler= new BtnEvtHandler();
(jumpBtn).addActionListener(okButtonHandler);
menuPanel.add(jumpBtn);
Now I want to add another button as below which can have the same class as event handler but dispatches to different actionPerformed as mentioned in above code.
JButton moveBtn= new JButton("MOVE");
menuPanel.add(moveBtn);
(moveBtn).addActionListener(okButtonHandler);
You can't reuse one ActionListener and expect it to call a different method depending on the button you attach it to. The contract of ActionListener has one method that gets called. But you can check the source of the event and have flow control based on that. Here's an example:
package com.sandbox;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.WindowConstants;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
public class SwingSandbox {
public static void main(String[] args) throws IOException {
JFrame frame = buildFrame();
JPanel pane = new JPanel();
MyActionListener myActionListener = new MyActionListener();
JButton button1 = new JButton("Button1");
button1.addActionListener(myActionListener);
pane.add(button1);
JButton button2 = new JButton("Button2");
button2.addActionListener(myActionListener);
pane.add(button2);
frame.add(pane);
}
private static JFrame buildFrame() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setSize(200, 200);
frame.setVisible(true);
return frame;
}
private static class MyActionListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
JButton source = (JButton) e.getSource();
if ("Button1".equals(source.getText())) {
System.out.println("You clicked button 1");
} else {
System.out.println("You clicked button 2");
}
}
}
}