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("");
}
Related
I am trying to make a text adventure game that includes puzzles in every room. I have direction buttons to go to the next rooms, but I want the buttons to display a message if they haven't answered the question correctly yet. When they answer it then the game will show them which way they can go and the buttons will work. Is there anyway to do this?
I tried doing this, but the only way this works is if they type the answer and leave it in the textfield instead of typing enter. I don't want that though.
private void northBtnMouseClicked(java.awt.event.MouseEvent evt) {
if(!playerInput.getText().equals(currentRoom.getAns()))
{
gameScreen.append("\nThe doors are locked until you answer the puzzle.");
}
else
{
String direction = "north";
Room nextRoom = currentRoom.getExits(direction);
if(nextRoom == null)
{
gameScreen.append("\n There is not an exit that way\n");
}
else
{
currentRoom = nextRoom;
gameScreen.append("\n" + currentRoom.getLongDescription());
}
}
}
There a number of ways this might be achieved, one of the simplest might be to simply disable the button(s) until the user enters what you want.
The (minor) problem with this is that it will require the user to press the "action" key (typically Enter) until the input can be validated. Not a big deal, but its not always obvious to the user.
Another approach would be to use a DocumentListener to monitor for changes to the underlying Document and validate the input in real time.
This approach allows you to provide real time feedback to the user as they type. It also allows the user to paste content into the field and have it validated as well, which is not done if you use a KeyListener.
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
public class TestDoc {
public static void main(String[] args) {
new TestDoc();
}
public TestDoc() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private JTextField field;
private JButton button;
public TestPane() {
button = new JButton("Make it so");
button.setEnabled(false);
field = new JTextField(10);
field.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
validateInput();
}
});
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
add(field, gbc);
add(button, gbc);
field.getDocument().addDocumentListener(new DocumentListener() {
#Override
public void insertUpdate(DocumentEvent e) {
validateInput();
}
#Override
public void removeUpdate(DocumentEvent e) {
validateInput();
}
#Override
public void changedUpdate(DocumentEvent e) {
validateInput();
}
});
}
public void validateInput() {
String text = field.getText();
if ("go".equals(text)) {
button.setEnabled(true);
} else {
button.setEnabled(false);
}
}
}
}
Have a look at Listening for Changes on a Document for more details
I just give you this example to give you an idea and start you up
Code:
public class NewClass {
public static void main(String... args) {
JButton jb = new JButton("Enter");
jb.setEnabled(false);
JTextField jt = new JTextField(15);
JFrame jf = new JFrame();
jf.setSize(200, 100);
FlowLayout layout = new FlowLayout();
jf.setLayout(layout);
jf.add(jb);
jf.add(jt);
jf.setLocationRelativeTo(null);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setVisible(true);
jt.addKeyListener((new KeyAdapter() {
#Override
public void keyReleased(KeyEvent e) {
JTextField textField = (JTextField) e.getSource();
String text = textField.getText();
textField.setText(text.toUpperCase());
if(!textField.getText().isEmpty())
jb.setEnabled(true);
else
jb.setEnabled(false);
}
}));
}
}
output:
Explanation:
There are many ways to accomplish what you want. For example, Key Listener and Document Listener.
The good practice is to use Document Listener because it is not depended on activities.
Note: there are other good ways to solve your issue but I thought this way is more easier for you to understand
Take a look at this comment
A DocumentListener would be better as that lets you react to any
changes to the text, whether or not they were triggered by a key press
(e.g. a paste from the clipboard), and you don't have to worry about
key presses that don't cause the text to change. – Ian Roberts
Source: http://docs.oracle.com/javase/tutorial/uiswing/events/keylistener.html
Using Document Listener Approach which is good practice and recommended
Code:
import java.awt.FlowLayout;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.Document;
public class DocumentListenerSample {
public static void main(String args[]) {
JButton jb = new JButton("Enter");
jb.setEnabled(false);
JTextField jt = new JTextField(15);
JFrame jf = new JFrame();
jf.setSize(200, 100);
FlowLayout layout = new FlowLayout();
jf.setLayout(layout);
jf.add(jb);
jf.add(jt);
jf.setLocationRelativeTo(null);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setVisible(true);
DocumentListener documentListener = new DocumentListener() {
#Override
public void changedUpdate(DocumentEvent documentEvent) {
printIt(documentEvent);
}
#Override
public void insertUpdate(DocumentEvent documentEvent) {
printIt(documentEvent);
}
#Override
public void removeUpdate(DocumentEvent documentEvent) {
printIt(documentEvent);
}
private void printIt(DocumentEvent documentEvent) {
Document source = documentEvent.getDocument();
int length = source.getLength();
if(length != 0)
jb.setEnabled(true);
else
jb.setEnabled(false);
}
};
jt.getDocument().addDocumentListener(documentListener);
jf.setSize(250, 150);
jf.setVisible(true);
}
}
Sure, you could either jbtn.setEnabled(false) until you had all your answers or (probably easier) keep an answer count accessible to your MouseClicked routine that simply ignores clicks until the questions are answered.
I am trying to make a Login Form with Java. I Cant get it working.
I have looked all over then internet for how to fix this, I can't find anything.
Code:
LoginFrame.java:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class LoginFrame extends JFrame
{
JPanel pane = new JPanel();
static JFormattedTextField username = new JFormattedTextField(16);
static JFormattedTextField password = new JFormattedTextField(16);
static JButton loginButton = new JButton("Login!");
static String input[];
public LoginFrame() throws IOException
{
super("Login");
setSize(300,150);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container con = this.getContentPane();
con.add(pane);
pane.add(new JLabel("Username"));
pane.add(username);
pane.add(new JLabel("Password"));
pane.add(password);
pane.add(loginButton);
#Override
IEventHandler eHandler = new IEventHandler();
#Override
loginButton.addActionListener(eHandler);
setVisible(true);
}
static String[] getInput()
{
return input;
}
}
IEventHandler.java:
import java.awt.event.*;
class IEventHandler implements ActionListener
{
public void actionPreformed(ActionEvent e)
{
if(e.getSource() == LoginFrame.loginButton){
LoginFrame.loginButton.setEnabled(false);
new AuthLIB().authenticate(LoginFrame.getInput());
}
}
public IEventHandler()
{
System.out.println("Event Handler Hooked");
}
}
You aren't overriding anything with-in the method body. These
#Override
IEventHandler eHandler = new IEventHandler();
#Override
loginButton.addActionListener(eHandler);
should just be
IEventHandler eHandler = new IEventHandler();
loginButton.addActionListener(eHandler);
and assuming you want ActionListener.actionPerformed(ActionEvent)
public void actionPreformed(ActionEvent e)
should use that annotation. You'd see the spelling mistake quicker anyway.
#Override
public void actionPerformed(ActionEvent e)
In my UI i have a JPopMenu with values as ,
for e.g A,B,C
The scenario is,
I opened the JPopupMenu and kept it open.
At back end with a timer running , it updates the content B to some other alphabet at frequent interval.
3.I want the JPopupMenu to get updated while it is kept open.
In current behavior if i close and open JPopupMenu the updated value shows up.
I tried repaint()but it doesn't do anything.
What is the best way to do this?? Am new to swings please help.
Menu items can change their content at run time just fine. Without seeing your code it's hard to tell what you're doing wrong, but here's a working example:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
public class PopupTest {
private static final String[] messages = {
"You are today's 1000th user!",
"You have won an internet!",
"Claim your prize!"
};
private PopupTest() {
JFrame frame = new JFrame("You have won");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel lbl = new JLabel("Check your prize!");
frame.setLocationByPlatform(true);
frame.add(lbl);
frame.pack();
final JPopupMenu menu = new JPopupMenu();
final JMenuItem item = new JMenuItem(messages[0]);
menu.add(item);
menu.add(new JMenuItem("Another item that does not work"));
final Timer timer = new Timer(1000, new ActionListener() {
int count;
#Override
public void actionPerformed(ActionEvent e) {
count++;
count %= messages.length;
item.setText(messages[count]);
}
});
menu.addPopupMenuListener(new PopupMenuListener() {
#Override
public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
}
#Override
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
timer.stop();
}
#Override
public void popupMenuCanceled(PopupMenuEvent e) {
timer.stop();
}
});
lbl.addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
maybeShowPopup(e);
}
#Override
public void mouseReleased(MouseEvent e) {
maybeShowPopup(e);
}
private void maybeShowPopup(MouseEvent e) {
if (e.isPopupTrigger()) {
menu.show(e.getComponent(), e.getX(), e.getY());
timer.start();
}
}
});
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new PopupTest();
}
});
}
}
Try to use .revalidate() with .repaint() it might help.
The docs suggest that the revalidate method is called every time something like size changes and manually calling it with repaint seems to solve problems like these.
a basic problem that i can't figure out, tried a lot of things and can't get it to work, i need to be able to get the value/text of the variable
String input;
so that i can use it again in a different class in order to do an if statement based upon the result
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
public class pInterface extends JFrame {
String input;
private JTextField item1;
public pInterface() {
super("PAnnalyser");
setLayout(new FlowLayout());
item1 = new JTextField("enter text here", 10);
add(item1);
myhandler handler = new myhandler();
item1.addActionListener(handler);
System.out.println();
}
public class myhandler implements ActionListener {
// class that is going to handle the events
public void actionPerformed(ActionEvent event) {
// set the variable equal to empty
if (event.getSource() == item1)// find value in box number 1
input = String.format("%s", event.getActionCommand());
}
public String userValue(String input) {
return input;
}
}
}
You could display the window as a modal JDialog, not a JFrame and place the obtained String into a private field that can be accessed via a getter method. Then the calling code can easily obtain the String and use it. Note that there's no need for a separate String field, which you've called "input", since we can easily and simply extract a String directly from the JTextField (in our "getter" method).
For example:
import java.awt.Dialog.ModalityType;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import javax.swing.*;
import javax.swing.text.JTextComponent;
public class TestPInterface {
#SuppressWarnings("serial")
private static void createAndShowGui() {
final JFrame frame = new JFrame("TestPInterface");
// JDialog to hold our JPanel
final JDialog pInterestDialog = new JDialog(frame, "PInterest",
ModalityType.APPLICATION_MODAL);
final MyPInterface myPInterface = new MyPInterface();
// add JPanel to dialog
pInterestDialog.add(myPInterface);
pInterestDialog.pack();
pInterestDialog.setLocationByPlatform(true);
final JTextField textField = new JTextField(10);
textField.setEditable(false);
textField.setFocusable(false);
JPanel mainPanel = new JPanel();
mainPanel.add(textField);
mainPanel.add(new JButton(new AbstractAction("Get Input") {
#Override
public void actionPerformed(ActionEvent e) {
// show dialog
pInterestDialog.setVisible(true);
// dialog has returned, and so now extract Text
textField.setText(myPInterface.getText());
}
}));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
// by making the class a JPanel, you can put it anywhere you want
// in a JFrame, a JDialog, a JOptionPane, another JPanel
#SuppressWarnings("serial")
class MyPInterface extends JPanel {
// no need for a String field since we can
// get our Strings directly from the JTextField
private JTextField textField = new JTextField(10);
public MyPInterface() {
textField.addFocusListener(new FocusAdapter() {
#Override
public void focusGained(FocusEvent e) {
JTextComponent textComp = (JTextComponent) e.getSource();
textComp.selectAll();
}
});
add(new JLabel("Enter Text Here:"));
add(textField);
textField.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
Window win = (Window) SwingUtilities.getWindowAncestor(MyPInterface.this);
win.dispose();
}
});
}
public String getText() {
return textField.getText();
}
}
A Good way of doing this is use Callback mechanism.
I have already posted an answer in the same context.
Please find it here JFrame in separate class, what about the ActionListener?.
Your method is a bit confusing:
public String userValue(String input) {
return input;
}
I guess you want to do something like this:
public String getInput() {
return input;
}
public void setInput(String input) {
this.input = input;
}
Also your JFrame is not visible yet. Set the visibility like this setVisible(true)
When it is clicked on JLabel, I want to understand if the click was on "Icon part", or "Text part" of the JLabel, so that different action can be taken. Is there a clever way to do that? Or just I have to solve it relatively with the coordinates of the icon and text?
+1 to #aymeric comment.
What about having two different JLabels
However I do understand why you might be hesitating
negative: requires maintenance of 2 labels.
My clever (:P) solution to this is create your own abstract component - which accepts icon and text as parameters for constructor - by extending JPanel and than adding 2 JLabels to the JPanel, each label has its on MouseAdapter which calls abstract method xxxClicked() (thus any implementing class must override these methods).
Here is an example I made:
import java.awt.FlowLayout;
import java.awt.Image;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Test {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ImageIcon ii = null;
try {
//I dont remmend getScaledInstance just used it for speed of code writing
ii = new ImageIcon(ImageIO.read(new URL("http://www.candonetworking.com/java.gif")).getScaledInstance(32, 32, Image.SCALE_SMOOTH));
} catch (Exception ex) {
ex.printStackTrace();
}
MyLabel ml = new MyLabel(ii, "Something") {
#Override
void iconClicked() {
System.out.println("Icon clicked");
}
#Override
void textClicked() {
System.out.println("Text clicked");
}
};
frame.add(ml);
frame.pack();
frame.setVisible(true);
}
});
}
}
abstract class MyLabel extends JPanel {
JLabel iconLabel;
JLabel textLabel;
MouseAdapter iconMA;
MouseAdapter textMA;
public MyLabel(ImageIcon icon, String text) {
iconLabel = new JLabel(icon);
textLabel = new JLabel(text);
iconMA = new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent me) {
super.mouseClicked(me);
iconClicked();
}
};
textMA = new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent me) {
super.mouseClicked(me);
textClicked();
}
};
iconLabel.addMouseListener(iconMA);
textLabel.addMouseListener(textMA);
add(iconLabel);
add(textLabel);
}
abstract void iconClicked();
abstract void textClicked();
public JLabel getIconLabel() {
return iconLabel;
}
public JLabel getTextLabel() {
return textLabel;
}
}