I am relatively new to Java and recently I have been working on a GUI based html parser.
The interface is simple, consisting of:
JTextField for entering a search term
JButton b1 to initiate the search
JButton b2 to exit
JButton b3 to display an URL in the browser using cmd prmt.
The problem arises with b3.
Here is a code sample:
while (mstyle2.find())
{
String s=mstyle2.group(0);
String pattern = "(?i)(<cite.*?>)(.+?)(</cite>)";
String updated = s.replaceAll(pattern, "$2");
String pattern2 = "(?i)(<b>)(.+?)(</b>)";
String updated2 = updated.replaceAll(pattern2, "$2");
String pattern3 = "(http://)";
boolean c=true;
String updated32 = updated2.replaceAll(pattern3, "");
String pattern32 = "(https://)";
final String updated3 = updated32.replaceAll(pattern32,"");
try {
URL url2 = new URL("http://"+updated3);
URLConnection conne = url2.openConnection();
conne.connect();
} catch (MalformedURLException e) {
c=false;
} catch (IOException e) {
c=false;//checks validity of url
}
if(c) {
Process p=Runtime.getRuntime().exec("cmd /c start http://"+updated3);
}
}
The idea is that the following command line should only be executed when b3 is pressed. Otherwise the loop will not execute, and remain in that line until the button is pressed.
Process p=Runtime.getRuntime().exec("cmd /c start http://"+updated3);
However, I cannot find any viable way to properly implement the ActionListener method in order to make this possible.
In most of my tries, once b3 is pressed, all link open at once (thus beating the purpose of the b3) and not one by one with every click of b3.
Solution
JButtons has a method called addActionListener(). This method allows you to attach a runnable to a button, so the code is only called when it is clicked.
b3.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
// Your code here!
}
});
What is this doing?
Well this is adding a new ActionListener object to your button. However, ActionListener has an abstract method, actionPeformed that needs an implementation. You are simply providing the code in the constructor.
Related
I am learning Java Swing. I am trying to develop as simple app for learning purpose. There is are multiple issues in following code. I try to read a csv file and populate JComboBox on button click.
public class MyForm {
private JButton btnRead;
private JButton btnRead2;
private JComboBox cbCodes;
private JPanel mainPanel;
private DefaultComboBoxModel comboBoxModel;
public MyForm(){
// issue 1: I always get null pointer exception in this line
comboBoxModel = new DefaultComboBoxModel();
cbCodes = new JComboBox(comboBoxModel);
btnRead.addActionListener( e -> {
List<String[]> data = readData();
comboBoxModel.removeAllElements();
data.forEach(item -> comboBoxModel.addElement(item));
});
// issue 2: Since DefaultComboBoxModel was not working. I tried without it. As this I get correct data in the array. But when I make JComboBox with array. Nothing is filled. It is empty.
btnRead2.addActionListener( e -> {
List<String[]> data = readData();
String[] array = new String[data.size()];
data.toArray(array);
cbCodes = new JComboBox(array);
});
}
// issue 3: I can't complie the code without this empty method. Why do I need it?
// error: Form contains components with Custom Create option but no createUIComponents() method
void createUIComponents(){
}
public List<String[]> readData() {
String file = "data.csv";
List<String[]> content = new ArrayList<>();
try(BufferedReader br = new BufferedReader(new FileReader(file))) {
String line = "";
while ((line = br.readLine()) != null) {
if(line.contains("\"")){
content.add(line.split(" "));
}
content.add(line.split(","));
}
} catch (FileNotFoundException e) {
//Some error logging
} catch (IOException e) {
e.printStackTrace();
}
return content;
}
public static void main(String[] args) {
JFrame frame = new JFrame("MyForm");
frame.setContentPane(new MyForm().mainPanel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
}
I make my question in the source code with the comment to show exactly here those issues are involved.
You don't get the NullPointerException in the lines you indicated, but in the line btnRead.addActionListener( e -> { because btnRead has not been initialized yet!
When you create a new JComboBox, you have to add it to the panel, too. Just creating it with new will not display it. But the real problem behind it is: you're using the model wrong. Write
comboBoxModel.removeAllElements();
for (final String string : array) {
comboBoxModel.addElement(string);
}
to solve that.
The problem you have here does not lie within the code you provided, but from another component. At some point, someone used a UI designer. Those designers usually create initialization methods, just like createUIComponents. See where that method gets called.
Synopsis:
All in all, your code is really chaotic. Restructure from new, this will clean up a lot of problems.
And initialize UI components as soon as possible, best do it in the declaration line: private final JButton btnRead = new JButton("Read!");
I strongly recommend using an IDE like Eclipse or IntelliJ that will help you write clean code and see and correct problems easier.
I wrote a media player in Java using the Java Media Framework (yeah, I know it's really old!)
on Netbeans, and I have this problem:
I have a browse button which selects the file, initializes the Player and starts playback. The problem is, the button is in private void and hence the player is not accessible across the form.
This is the jButton code:
private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {
Player pla;
try{
FileDialog fd = new FileDialog(this, "Select File", FileDialog.LOAD);
fd.show();
String filename = fd.getDirectory() + fd.getFile();
pla=Manager.createPlayer(new MediaLocator("file:///"+filename));
pla.start();
}
catch (Exception e){
System.out.println(e.toString());
}
// TODO add your handling code here:
}
How do I make the player pla across the Jpanel so that any button in the panel (Netbeans automatically sets all jButtons to private void) can access the player pla?
P.S.: Someone please suggest me a modern API (other than Xuggler) for Java media, preferably, using FFMPEG but not necessarily.
Thanks!
The class player can have a method
By reflexion you can return any button
JButton getButton(String nameButton) throws Exception{
Field field = clazz.getClass().getField(nameButton);
return (JButton) field.get(this);
}
I want to change button text when i click on it, but it does not appears on the GUI. In intellje IDE i can see it is changed but why does not appear in GUI?
This is code snip:
final WebLabel loading = new WebLabel("Disconnected...", IconLib.ICON_19X17_THICK_ARROW_RIGHT_LIGHTBLUE.getIcon(), SwingConstants.CENTER);
final WebLabel ipLabel = new WebLabel(host);
final JPanel horizontalMiddlePanel = new JPanel();
final WebButton disconnect = new WebButton("Connect", IconLib.ICON_16X16_QUESTIONMARK_ON_BLUE_CIRCLE.getIcon());
disconnect.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (loading.getText().equals("Connected...")) {
loading.setText("Disconnected...");
loading.setIcon(IconLib.ICON_19X17_THICK_ARROW_RIGHT_LIGHTBLUE.getIcon());
disconnect.setText("Connect");
} else {
loading.setText("test");
loading.setIcon(IconLib.ICON_19X17_THICK_ARROW_RIGHT.getIcon());
ipLabel.setText(ipLabel.getText().replace(" Unreachable try again",""));
ipLabel.setForeground(Color.green);
disconnect.setText("Connecting");
callflexConnection(ipLabel, 3001, loading, disconnect);
}
}
});
than not possible without spliting code to to the two parts
1) update JButton#setText
then
2) executing rest of code
by delaing by using javax.swing.Timer
execute from SwingWorker
wrap inside Runnble#Thread,
3) this code is executed on EDT, then all changes are done on EDT, end in same/one moment
It's hard to tell if it's the source of your current problem or not, but performing logic in code based on the current text on a button is a flimsy way to do things. You should maintain that connection state in a dedicated variable. Something like this:
private enum ConnState {
CONN_DISCONNECTED,
CONN_CONNECTING,
CONN_CONNECTED,
};
private ConnState connState;
private void setConnState(ConnState connState) {
this.connState = connState;
switch (connState) {
case CONN_DISCONNECTED:
loading.setText("Disconnected");
disconnect.setText("Connect");
break;
case CONN_CONNECTING:
loading.setText(...etc...);
disconnect.setText(...);
break;
case CONN_CONNECTED:
loading.setText(...);
disconnect.setText(...);
break;
}
}
And call this when setting up the GUI to initialize the button text and connState:
setConnState(CONN_DISCONNECTED);
Then you can reason robustly about the current state of the program by checking the connState variable instead of having to synchronize button strings everywhere.
hi i have a full screen program which i dont want people to close unless they have a password i have this code at the moment
public void windowClosing(WindowEvent arg0)
{
System.out.println("HERE");
String inputValue = JOptionPane.showInputDialog("Please input the closeword");
if (inputValue != "closeplz")
{
}
}
in the if statement i want it to stop the method so that the program doesent close. any help would be greatly aprecheated thanks ste
You have to call
setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
on (or within) the JFrame instance. Then the frame will not close unless you do it manually, though windowClosing() will still be called. Inside it, you can then conditionally call
System.exit(1);
which will end the application. Be sure to do any necessary cleanup first.
Check out Closing an Applicaton for a simple class to help you with this. You would need to provide the custom close action that prompts the user for the password.
Using your simple example the code would be:
Action ca = new AbstractAction()
{
public void actionPerformed(ActionEvent e)
{
JFrame frame = (JFrame)e.getSource();
String inputValue = JOptionPane.showInputDialog("Please input the closeword");
if (! inputValue.equals("closeplz"))
{
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
}
}
};
CloseListener cl = new CloseListener(ca);
i write a method to create a form(3 buttons and a textBox), then i call it in main.
but when i run program, before i enter information in the form (method form6 ),
Other commands that are executed! "s4 and ontname chenged in the form".
this is a part of my code:::::::::::
//////////////////////////////////////////////////////////////////////////
public static void main(String[] args) {
System.out.println("*begin main*"); // call form method
String s4= form6(); // s4 is returned by method.
System.out.println("s3333*"+s4);
System.out.println("ont:"+ontname);//it's global }
//////////////////////////////////////////////////////////////////////////
i have 2 questions:::
1--- While the form is running, other commands are executed!
What is their order execution?
2. --- i want to define a button to when i click it,it closes the form.
thanks all.
If I get your code correctly, ontname is either (1) a class member (declared outside a method) or (2) a local variable, which is declared in the method that contains this code snippet.
In both cases there is no need to "return" ontname just because it is not declared inside the anonymous ActionListener instance.
The following example illustrates a typical pattern for this problem:
public void someMethod() {
// ...
button2.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
String filename = File.separator+"c:";
JFileChooser fc = new JFileChooser(new File(filename));
fc.showOpenDialog(null);
File selFile = fc.getSelectedFile();
setOntName(selFile.getPath()); // <-- here we call another method
}
});
// ...
}
void setOntName(String ontName) {
// do something with ontName
}
Alternativly: declare ontName as a static class member (only):
private static String ontName = ""; // <-- accessible from main method
public static void main(String[] args) {
// ...
}
// more methods.
You can't return a value in this Method because the ActionListenerInterface does not allow this. But you can call another method from within the actionPerformed() method and pass the ontname to it.
You can also close the third button in the new method. Or define the third button as final and use it in the actionPerformed() method.
E.g.
button2.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
String filename = File.separator+"c:";
JFileChooser fc = new JFileChooser(new File(filename));
fc.showOpenDialog(null);
File selFile = fc.getSelectedFile();
ontname=selFile.getPath();
System.out.println("filepath: "+ontname); //it works correctly.
anotherMethod(ontname);
}
});
private void anotherMethod(String path) {
//doSomething with the path
//close third button here
}
You could probably define your variable ontname as global, outside of your function:
var ontname = null;
button2.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
// ...
ontname=selFile.getPath();
}
});
// ...
System.out.println("filepath: "+ontname);
If you want to remember the values, then they should be class level variables.
But, generally, you would want to pass these to some other method to do some processing on them (or, say, persist them in a file). You can pass these as parameters to the other method.
(The second one is better in most cases, I don't know much about your app, so I am unable to give one answer)
There are other problems with your code:
You need to check whether the use has clicked the "Ok" or "Cancel" button in the open dialog to decide whether to get the file or not.
String filename = File.separator+"c:"; does not really make sense. Perhaps you meant String filename = "c:"+File.separator; But even this is not very useful. File.separator is for getting the platform specific file separator char (\ in Windows, / on linux) but since you are hard coding c:, you are anyway constrainting your app to Windows. You might want to have a better platform independent way (start at the "default" path, new JFileChooser() without arguments, and then remember the path the user last used, and proceed from there)
If the argument to the showOpenDialog method is your parent frame, then the dialog would be centered on the parent frame, and would, in most cases, look nicer.
You might also want to relook your variable names.
button2.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
String filename = File.separator+"c:";
JFileChooser fc = new JFileChooser(new File(filename));
int option = fc.showOpenDialog(null);
if(option = JFileChooser.APROVE_OPTION)
{
File selFile = fc.getSelectedFile();
String ontname=selFile.getPath();
System.out.println("filepath: "+ontname); //it works correctly.
doSomeOperation(ontname); //Or, declare ontname as a class level variable.
}
}
});