EDIT: Huge code re-organisation, old question here: http://pastebin.com/Mbg4dYiY
I have created a basic program that is designed to show the weather in a window using Swing. I am developing using IntelliJ and I have used the UI builder in that. I am attempting to fetch some information from the Weather Underground servers and then make a JLabel called weatherlabel display this information. However, the JLabel doesn't actually change in the window; it just stays as 'Weather Will Go Here'. How do I fix this?
Here is my main.java:
public class main {
public static void main(String[] args) {
System.out.println("Hello World!");
Display d = new Display();
d.getandsetWeather();
}
}
Here is my Display.java:
public class Display {
Display disp = this;
public JPanel myPanel;
public JLabel weatherfield;
private JButton button1;
public void init() {
JFrame frame = new JFrame("Display");
frame.setContentPane(new Display().myPanel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setMinimumSize(new Dimension(480, 234));
frame.pack();
frame.setVisible(true);
}
public void getandsetWeather() {
String editedline = null;
init();
try {
// Construct data
String data = URLEncoder.encode("key1", "UTF-8") + "=" + URLEncoder.encode("value1", "UTF-8");
data += "&" + URLEncoder.encode("key2", "UTF-8") + "=" + URLEncoder.encode("value2", "UTF-8");
// Send data
URL url = new URL("http://api.wunderground.com/api/772a9f2cf6a12db3/geolookup/conditions/q/UK/Chester.json");
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
wr.write(data);
wr.flush();
// Get the response
BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line;
while ((line = rd.readLine()) != null) {
if( line.contains("\"weather\":")) {
System.out.println(line);
editedline = line.replace("\"weather\":\"", "");
editedline = editedline.replace("\",", "");
System.out.println(editedline);
weatherfield.setText(editedline);
}
}
wr.close();
rd.close();
weatherfield.setText(editedline);
System.out.println(weatherfield.getText());
weatherfield.repaint();
weatherfield.revalidate();
} catch (Exception e) {
System.out.println("Error!" + e);
}
}
}
When I run the program, this is printed to the log:
Hello World!
"weather":"Scattered Clouds",
Scattered Clouds
Scattered Clouds
You seem to have a strange understanding of OOP and code-flow
You have to main methods, one of which you are trying to call the other main method. Don't do that. A program should only have one main method. You should never have to this
Display.main(new String[]{});
Why even have this ChangeWeatherLabelText class? There is only one method, that doesn't seem to be needed in it's own class. Your instantiation if Display in that method does nothing to the rest of the program. So you call has no effect on the label.
Instead of 3, put that method in the class that actually has the label and just reference the label field in the method.
Also, GetWeather just seems like a helper class with a helper method. "Helper" class methods are useless if they don't return something.
IMHO, you should restructure your entire program. Some things may work now, but there's a lot of bad practice going on in your code
If I were to write this program, all the code would be in one file. If you insist on them being in separate files, you need to learn how to use constructors and how to pass objects to them. That is how you are going to manipulate objects from other classes. That is unless you understand the MVC model, which may be a little advance at this point for you.
UPDATE with OP update of code
Test this out and be sure to read the comments so you can see what I did. Let me know if you have any question.
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class main {
public static void main(String[] args) {
System.out.println("Hello World!");
new Display(); // <-- just instantiate
}
}
class Display {
Display disp = this;
public JPanel myPanel; // <--------- Haven't been initialized
public JLabel weatherfield;
private JButton button1;
public Display() { // you need constructor to call init
init();
}
public void init() {
myPanel = new JPanel(new BorderLayout()); // initialize
weatherfield = new JLabel(" "); // initialize
button1 = new JButton("Button"); // initialize
myPanel.add(weatherfield, BorderLayout.CENTER);
myPanel.add(button1, BorderLayout.SOUTH);
button1.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
getandsetWeather(); // <-------- add listener to call getandsetweather
}
});
JFrame frame = new JFrame("Display");
frame.setContentPane(myPanel); // <--------------------- fix 1
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setMinimumSize(new Dimension(480, 234));
frame.pack();
frame.setVisible(true);
}
public void getandsetWeather() {
String editedline = null;
init();
try {
// Construct data
String data = URLEncoder.encode("key1", "UTF-8") + "=" + URLEncoder.encode("value1", "UTF-8");
data += "&" + URLEncoder.encode("key2", "UTF-8") + "=" + URLEncoder.encode("value2", "UTF-8");
// Send data
URL url = new URL("http://api.wunderground.com/api/772a9f2cf6a12db3/geolookup/conditions/q/UK/Chester.json");
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
wr.write(data);
wr.flush();
// Get the response
BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line;
while ((line = rd.readLine()) != null) {
if( line.contains("\"weather\":")) {
System.out.println(line);
editedline = line.replace("\"weather\":\"", "");
editedline = editedline.replace("\",", "");
System.out.println(editedline);
weatherfield.setText(editedline);
}
}
wr.close();
rd.close();
weatherfield.setText(editedline);
System.out.println(weatherfield.getText());
weatherfield.repaint();
weatherfield.revalidate();
} catch (Exception e) {
System.out.println("Error!" + e);
}
}
}
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
I am trying to create a java application that translates spanish into english. I am facing problem while translating spanish into english. But when i translate english into spansih it works. Here is my code. Here is my code. Can you please tell me my error. This code is working right now but when i change the values of fromLang to toLang from en to es it does not work.
import java.io.BufferedReader;
import java.io.OutputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Arrays;
public class GuiApp1 {
private static final String CLIENT_ID = "FREE_TRIAL_ACCOUNT";
private static final String CLIENT_SECRET = "PUBLIC_SECRET";
private static final String ENDPOINT = "http://api.whatsmate.net/v1/translation/translate";
public static void main(String[] args) throws Exception {
GuiApp1 g = new GuiApp1();
JFrame f=new JFrame();//creating instance of JFrame
f.setAlwaysOnTop( true );
JButton b=new JButton("Translate");//creating instance of JButton
b.setBounds(90,150,100, 40);//x axis, y axis, width, height
f.add(b);//adding button in JFrame
JTextArea t1,t2;
t1=new JTextArea(2,2);
String spanish;
t1.setBounds(50,100, 200,30);
t2=new JTextArea(2,2);
t2.setBounds(50,200, 200,30);
f.add(t1); f.add(t2);
f.setPreferredSize(new Dimension(200, 900));
f.setLayout(null);//using no layout managers
f.setVisible(true);//making the frame visible
b.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent ae){
String text = t1.getText();
text = text.trim();
text = text.toLowerCase();
System.out.println(text);
String fromLang = "en";
String toLang = "es";
//String text = "Cuál es su nombre";
try{
translate(fromLang, toLang, text);
}catch(Exception e){
System.out.println(e);
}
}
});
}
/**
* Sends out a WhatsApp message via WhatsMate WA Gateway.
*/
public static void translate(String fromLang, String toLang, String text) throws Exception {
// TODO: Should have used a 3rd party library to make a JSON string from an object
String jsonPayload = new StringBuilder()
.append("{")
.append("\"fromLang\":\"")
.append(fromLang)
.append("\",")
.append("\"toLang\":\"")
.append(toLang)
.append("\",")
.append("\"text\":\"")
.append(text)
.append("\"")
.append("}")
.toString();
URL url = new URL(ENDPOINT);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("X-WM-CLIENT-ID", CLIENT_ID);
conn.setRequestProperty("X-WM-CLIENT-SECRET", CLIENT_SECRET);
conn.setRequestProperty("Content-Type", "application/json");
OutputStream os = conn.getOutputStream();
os.write(jsonPayload.getBytes());
os.flush();
os.close();
int statusCode = conn.getResponseCode();
System.out.println("Status Code: " + statusCode);
BufferedReader br = new BufferedReader(new InputStreamReader(
(statusCode == 200) ? conn.getInputStream() : conn.getErrorStream()
));
String output;
while ((output = br.readLine()) != null) {
System.out.println(output);
}
conn.disconnect();
}
}
Perhaps you've now exceeded the Free Trial usage limit of 10.
In any case, the code does work. It will translate from English to Spanish OR Spanish to English. All you need to do is make sure you have a means to select which translation direction you want to go with. Currently you do not have this and are translating via a default of en to es. If you change the fromLang variable contents to "es" and the toLang variable contents to en and enter a Spanish word into the JTextArea t1 then hit the Translate button you will receive the translation into the Console Window (instead of the JTextArea, t2). The received string should be placed into JTextArea, t2. In order to place the returned string into the JTextArea t2 you will want to make the tranlate() method return a String type then in the while loop at the bottom of the method, instead of sending the returned data to console do something like this:
public static String translate(String fromLang, String toLang, String text) throws Exception {
// ... Most method code here ...
String output;
StringBuilder sb = new StringBuilder();
while ((output = br.readLine()) != null) {
sb.append(output).append(System.lineSeparator());
System.out.println(output); // Optional - For testing
}
conn.disconnect();
return sb.toString();
}
Now, where the translate() method is called, do this instead:
try {
String translation = translate(fromLang, toLang, text);
t2.setText(translation);
}
catch (Exception e) {
System.out.println(e);
}
Now the returned translation will be placed within the t2 JTextArea. I have taken the above mentioned modifications and applied them to your code provided below:
import java.io.BufferedReader;
import java.io.OutputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.border.Border;
public class Translator {
private static final String CLIENT_ID = "FREE_TRIAL_ACCOUNT";
private static final String CLIENT_SECRET = "PUBLIC_SECRET";
private static final String ENDPOINT = "http://api.whatsmate.net/v1/translation/translate";
#SuppressWarnings("Convert2Lambda")
public static void main(String[] args) throws Exception {
Translator g = new Translator();
JFrame f = new JFrame();//creating instance of JFrame
f.setTitle("Translator");
f.setAlwaysOnTop(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setPreferredSize(new Dimension(295, 300));
f.setLayout(null); //using no layout manager (*** BAD IDEA!! ***)
String[] transDirection = {"English To Spanish", "Spanish To English"};
JComboBox<String> jc = new JComboBox<>(transDirection);
jc.setSelectedIndex(0);
jc.setBounds(60, 30, 160, 25);
f.add(jc);
JButton b = new JButton("Translate");//creating instance of JButton
b.setBounds(90, 140, 100, 30);//x axis, y axis, width, height
f.add(b);//adding button in JFrame
Border border = BorderFactory.createLineBorder(Color.decode("#33acff"));
JTextArea t1 = new JTextArea(2, 2);
t1.setBounds(40, 80, 200, 50);
t1.setBorder(border);
t1.setLineWrap(true);
t1.setWrapStyleWord(true);
JScrollPane sp1 = new JScrollPane(t1);
sp1.setBounds(40, 80, 200, 50);
// ---------------------
JTextArea t2 = new JTextArea(2, 2);
t2.setBounds(40, 180, 200, 50);
t2.setBorder(border);
t2.setLineWrap(true);
t2.setWrapStyleWord(true);
JScrollPane sp2 = new JScrollPane(t2);
sp2.setBounds(40, 180, 200, 50);
f.add(sp1, BorderLayout.CENTER);
f.add(sp2, BorderLayout.CENTER);
f.pack();
f.setVisible(true);//making the frame visible
f.setLocationRelativeTo(null); // Must be after setVisible().
t1.requestFocus(); // Set focus on t1 when started
// Button Action Listener...
b.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
String text = t1.getText().trim();
//Make sure there is text to translate...
if (text.equals("")) {
JOptionPane.showMessageDialog(f, "There is no text supplied to translate!",
"Translation Error!", JOptionPane.WARNING_MESSAGE);
return; // Get out of this event.
}
// Get selected language translation direction...
String fromLang = "";
String toLang = "";
switch (jc.getSelectedItem().toString().toLowerCase()) {
case "english to spanish":
fromLang = "en";
toLang = "es";
break;
case "spanish to english":
fromLang = "es";
toLang = "en";
break;
default:
fromLang = "en";
toLang = "es";
}
try {
String translation = translate(fromLang, toLang, text);
t2.setText(translation);
}
catch (Exception e) {
System.out.println(e);
}
}
});
}
/**
* Sends out a WhatsApp message via WhatsMate WA Gateway.<br><br>
* #param fromLang
* #param toLang
* #param text
* #return
* #throws java.lang.Exception
*/
public static String translate(String fromLang, String toLang, String text) throws Exception {
// TODO: Should have used a 3rd party library to make a JSON string from an object
String jsonPayload = new StringBuilder()
.append("{")
.append("\"fromLang\":\"")
.append(fromLang)
.append("\",")
.append("\"toLang\":\"")
.append(toLang)
.append("\",")
.append("\"text\":\"")
.append(text)
.append("\"")
.append("}")
.toString();
URL url = new URL(ENDPOINT);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("X-WM-CLIENT-ID", CLIENT_ID);
conn.setRequestProperty("X-WM-CLIENT-SECRET", CLIENT_SECRET);
conn.setRequestProperty("Content-Type", "application/json");
// 'Try With Resources' used here to auto-close stream.
try (OutputStream os = conn.getOutputStream()) {
os.write(jsonPayload.getBytes());
os.flush();
}
int statusCode = conn.getResponseCode();
System.out.println("Status Code: " + statusCode);
BufferedReader br = new BufferedReader(new InputStreamReader(
(statusCode == 200) ? conn.getInputStream() : conn.getErrorStream()
));
String output;
StringBuilder sb = new StringBuilder();
while ((output = br.readLine()) != null) {
sb.append(output).append(System.lineSeparator());
System.out.println(output);
}
conn.disconnect();
return sb.toString();
}
}
On a side note: You use no layout manager (null) in the creation of your Form by choice. This is actually a bad idea, here's why (be sure to read the comments as well).
I use a CLI program regularly which is accessed through a docker container. Once I enter the container, I can start using my CLI program in question. The issue I'm having is I want to continue to interact with the same command line instance. Basically I'm trying to create a GUI program that will run "on top" of a CLI program. I just don't know how to keep sending commands to the same CLI instance:
List<String> command = new ArrayList<String>();
command.add("cmd.exe" );
command.add("/c");
command.add("docker-compose up -d");
System.out.println(command);
ProcessBuilder builder = new ProcessBuilder(command);
builder.inheritIO();
Map<String, String> environ = builder.environment();
Process process = builder.start();
InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
command.clear();
command.add("cmd.exe" );
command.add("/c");
command.add("docker ps");
System.out.println(command);
process = builder.start();
is = process.getInputStream();
isr = new InputStreamReader(is);
br = new BufferedReader(isr);
while ((line = br.readLine()) != null) {
System.out.println(line);
}
But this isn't working the way I would like it to. Above, you'll see I'm running two commands: docker-compose up -d and then docker ps. But I don't think they are running in the same instance. So if I were to change the directory in the first command, it's not going to remember the directory for the second command.
Also, it seems to be running my commands in reverse order from the order in the code.
Instances of class ProcessBuilder are intended to be short-lived, in my opinion. I don't think creating a new instance each time you want to create a new process wastes memory or other resources - but I'm only guessing.
In any case, to re-use a ProcessBuilder instance in order to execute several processes, you simply use its methods, like command(String...)
I wrote a small Swing app that lets the user enter a [operating system] command and displays that command's output. It's not production ready, but I hope it's enough to get you going.
Note that creating and handling a Process in java code is not simple nor intuitive. The article When Runtime.exec() won't helped me a lot. It is an ancient article, but nonetheless still relevant (again, in my opinion). Simply replace references to class Runtime in the article with class ProcessBuilder since the article was written before ProcessBuilder was added to the JDK.
Here is the code of my app. Please refer to the above-mentioned article in order to understand the ProcessBuilder related code. In order to understand the Swing code, I recommend the tutorial Creating a GUI With JFC/Swing
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
public class ProcExec implements ActionListener, Runnable {
private static final String CLEAR = "Clear";
private static final String EXIT = "Exit";
private static final String RUN = "Run";
private JTextArea commandOutput;
private JTextArea textArea;
private ProcessBuilder procBuilder;
public ProcExec() {
procBuilder = new ProcessBuilder();
}
public void actionPerformed(ActionEvent actionEvent) {
String actionCommand = actionEvent.getActionCommand();
if (CLEAR.equals(actionCommand)) {
textArea.setText("");
}
else if (EXIT.equals(actionCommand)) {
System.exit(0);
}
else if (RUN.equals(actionCommand)) {
try {
execute();
}
catch (Exception x) {
x.printStackTrace();
}
}
}
public void run() {
createAndDisplayGui();
}
private void createAndDisplayGui() {
JFrame frame = new JFrame("Process Executor");
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.add(createTopPanel(), BorderLayout.PAGE_START);
frame.add(createCommandPanel(), BorderLayout.CENTER);
frame.add(createButtonsPanel(), BorderLayout.PAGE_END);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JButton createButton(String text, int mnemonic, String tooltip) {
JButton button = new JButton(text);
button.setMnemonic(mnemonic);
button.setToolTipText(tooltip);
button.addActionListener(this);
return button;
}
private JPanel createButtonsPanel() {
JPanel buttonsPanel = new JPanel();
buttonsPanel.add(createButton(RUN, KeyEvent.VK_R, "Run entered command."));
buttonsPanel.add(createButton(CLEAR, KeyEvent.VK_C, "Removes entered command."));
buttonsPanel.add(createButton(EXIT, KeyEvent.VK_X, "Exit application."));
return buttonsPanel;
}
private JSplitPane createCommandPanel() {
textArea = new JTextArea(30, 40);
textArea.setLineWrap(true);
textArea.setWrapStyleWord(true);
JScrollPane cmdScrollPane = new JScrollPane(textArea);
commandOutput = new JTextArea(30, 80);
JScrollPane outputScrollPane = new JScrollPane(commandOutput);
JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
cmdScrollPane,
outputScrollPane);
return splitPane;
}
private JPanel createTopPanel() {
JPanel topPanel = new JPanel(new FlowLayout(FlowLayout.LEADING));
JLabel label = new JLabel("Enter a command...");
topPanel.add(label);
return topPanel;
}
private int execute() throws IOException, InterruptedException {
commandOutput.setText("");
String raw = textArea.getText();
String[] words = raw.split(" ");
String[] command = new String[words.length + 2];
command[0] = "cmd.exe";
command[1] = "/C";
System.arraycopy(words, 0, command, 2, words.length);
procBuilder.command(command);
Process proc = procBuilder.start();
ProcHandler stdout = new ProcHandler(proc.getInputStream());
ProcHandler stderr = new ProcHandler(proc.getErrorStream());
Thread stdoutThread = new Thread(stdout);
stdoutThread.start();
Thread stderrThread = new Thread(stderr);
stderrThread.start();
int status = proc.waitFor();
stderrThread.join();
stdoutThread.join();
return status;
}
private class ProcHandler implements Runnable {
private BufferedReader streamReader;
public ProcHandler(InputStream is) {
InputStreamReader isr = new InputStreamReader(is);
streamReader = new BufferedReader(isr);
}
public void run() {
try {
String line = streamReader.readLine();
while (line != null) {
SwingUtilities.invokeLater(new StreamLine(line));
line = streamReader.readLine();
}
}
catch (Exception x) {
throw new RuntimeException("Stream reading failed.", x);
}
}
}
private class StreamLine implements Runnable {
private final String text;
public StreamLine(String txt) {
text = txt + "\n";
}
public void run() {
ProcExec.this.commandOutput.append(text);
}
}
public static void main(String[] args) {
ProcExec instance = new ProcExec();
EventQueue.invokeLater(instance);
}
}
I've managed to make the input into a string which is available within the same class but I want to make it so the input string can be available in different classes. Current class is OpenDetails and I want the string selectedFile to be available in a different class called OpenFileInfo. How would I set it so the result from selectedFile can be stored in either selectedRequirement or make it available in other classes?
I'm new to Java so if someone could help thank you.
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import javax.swing.*;
public class OpenFile
{
String selectedRequirement = "";
public static void main(String a[])
{
JFrame parent = new JFrame();
String selectedFile;
selectedFile = JOptionPane.showInputDialog(parent, "Add a new module");
if(selectedFile.equalsIgnoreCase(selectedFile)){
//Makes the user input case insensitive
}
final JTextArea edit = new JTextArea(60,100);
JButton read = new JButton("Open "+ selectedFile +".txt");
read.addActionListener( new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
try
{
FileReader reader = new FileReader(selectedFile + ".txt");
BufferedReader br = new BufferedReader(reader);
edit.read( br, null );
br.close();
edit.requestFocus();
}
catch(Exception e2) { System.out.println(e2); }
}
});
JButton write = new JButton("Save "+ selectedFile + ".txt");
write.addActionListener( new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
try
{
FileWriter writer = new FileWriter(selectedFile + ".txt");
BufferedWriter bw = new BufferedWriter( writer );
edit.write( bw );
bw.close();
edit.setText("");
edit.requestFocus();
}
catch(Exception e2) {}
}
});
System.out.println("Module: " + selectedFile);
JFrame frame = new JFrame("Requirements");
frame.getContentPane().add( new JScrollPane(edit), BorderLayout.NORTH );
frame.getContentPane().add(read, BorderLayout.WEST);
frame.getContentPane().add(write, BorderLayout.EAST);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo( null );
frame.setVisible(true);
}
}
As you are running from a static context, you need to define selectedRequirement as static:
private static String selectedRequirement = "";
To make selectedRequirement equal to selectedFile, simply say selectedRequirement = selectedFile; towards the end of the main function (maybe where you print it already).
To make selectedRequirement available to other classes, you need to create a "getter function" in the OpenFIle class (outside of the main function) like:
public String getSelectedRequirement(){
return selectedRequirement;
}
As pointed out in the comments, it would be a good idea for you (or anyone who finds this in the future) to look at some tutorials on getters, setters, and general encapsulation.
I am working on project "Distributed Web Crawler using Java RMI".
The web crawls the pages and displays the URLs on two consoles-- a client one and a server one.
My problem is that I have to read these URLs from the console and display it under a Text Area in a window. I have tried a lot but the URLs are not getting displayed in Text Area.
However they were getting displayed on the console.
My code is:
import java.net.*;
import java.io.*;
import java.util.Date;
import java.io.File;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.Channels;
import java.rmi.*;
import java.util.*;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
class UCDemo implements ActionListener {
static String dispServerURL;
JFrame f1;
JPanel p1;
JLabel l1;
JLabel l2;
JTextField t1;
JTextArea t2;
JButton b1;
public void showFrame() {
f1 = new JFrame("Web Crawler");
p1 = new JPanel();
f1.setSize(7000, 7000);
f1.setVisible(true);
f1.setBackground(Color.pink);
f1.getContentPane().add(p1);
l1 = new JLabel("Enter seed URL");
t1 = new JTextField(100);
b1 = new JButton("Start");
l2 = new JLabel("Result");
t2 = new JTextArea(200, 200);
p1.add(l1);
p1.add(t1);
p1.add(b1);
p1.add(l2);
p1.add(t2);
b1.addActionListener(this);
}
public void actionPerformed(ActionEvent ae) {
try {
DispServerIntf dispServerIntf = (DispServerIntf) Naming.lookup(dispServerURL);
if (ae.getSource() == b1) {
String n1, k;
InputStreamReader ir = new InputStreamReader(System.in);
n1 = t1.getText();
int c = 0;
Document document = null;
URL hp = new URL(n1);
URLConnection hpcon = hp.openConnection();
try {
document = Jsoup.parse(hp, 3000);
} catch (IOException e) {
e.printStackTrace();
}
for (Element element : document.getElementsByTag("a")) {
c++;
ReadableByteChannel rbc = Channels.newChannel(hp.openStream());
FileOutputStream fos = new FileOutputStream("te.html");
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
if (c <= 7) {
Document doc_tmp = null;
URL hp_tmp = new URL(element.attr("href"));
t2.setText("" + hp_tmp);
URLConnection hpcontmp = hp_tmp.openConnection();
/**
* try { doc_tmp=Jsoup.parse(hp_tmp,3000); }
* catch(IOException e) {e.printStackTrace(); } for
* (Element ele: doc_tmp.getElementsByTag("a")) {
* System.out.println(ele.attr("href")); }
**/
ReadableByteChannel rbc_tmp = Channels.newChannel(hp_tmp.openStream());
FileOutputStream fos_tmp = new FileOutputStream("te" + c + ".html");
fos_tmp.getChannel().transferFrom(rbc_tmp, 0, Long.MAX_VALUE);
} else {
dispServerIntf.send(element.attr("href"));
}
}
/**
* BufferedReader in=new BufferedReader(new
* InputStreamReader(hpcon.getInputStream())); String inputline;
* while((inputline=in.readLine())!=null)
* System.out.println(inputline); in.close();
**/
}
} catch (Exception e) {
}
}
public static void main(String args[]) {
dispServerURL = "rmi://" + args[0] + "/DispServer";
new UCDemo().showFrame();
}
}
One problem is that you are doing all the work in a loop on the AWT thread (the "event dispatch thread") within the actionPerformed method, and updating the GUI in that loop.
This means that the GUI will not be updated properly (because the thread that updates the GUI is busy doing the HTML parsing work, and does not become free to process GUI events). You probably need to do the main loop in a separate thread, then update the GUI in the AWT thread using invokeLater().
See:
this tutorial, for example,
and the linked introduction to threading in Swing.
The official Swing Java Tutorial on this topic, which assumes you have read...
...the Concurrency lesson
Also, you always set the text to a single value, so you would only see the latest URL, not a list of them:
t2.setText("" + hp_tmp);
I'm making a program that requires to save user input. So I would like to know how to save JTextArea to text file and when you close and re-open program text is still in JTextArea.
Also sorry for my bad grammar.
package main;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.border.EtchedBorder;
public class main extends JFrame {
JLabel statusbar;
public main() {
initUI();
}
public final void initUI() {
JPanel panel = new JPanel();
statusbar = new JLabel("");
statusbar.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.RAISED));
panel.setLayout(null);
JTextArea area1;
area1 = new JTextArea(90, 25);
area1.setBounds(20, 20, 200, 25);
area1.setBackground(Color.white);
area1.setForeground(Color.BLACK);
area1.setText("");
panel.add(area1);
add(panel);
add(statusbar, BorderLayout.SOUTH);
setTitle("Viskis");
setSize(300, 200);
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
class ButtonListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
JButton o = (JButton) e.getSource();
String label = o.getText();
statusbar.setText("");
} }
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
main ms = new main();
ms.setVisible(true);
new main();
}
});
}
}
Here are some helper methods to help you read and write from Files. Look in the JavaDoc for getText() and setText() for getting and setting the text of the JTextArea.
I recommend reading the SwingWorker tutorials and using these methods in a SwingWorker, lest you lock up your GUI while saving/reading the Files
/**
* Writes a String text to a File specified by filename
*
* #param filename The filename/path of the File we would like to write the text to
* #param text The text to write to the File
*
*/
public static void writeToFile(String filename, String text) {
BufferedWriter writer = null; // This could go in a try-with-resources if you wanna get fancy
try {
writer = new BufferedWriter(new FileWriter(new File(filename))); // Open a File for writing
writer.write(text); // write the text to the file
} catch ( IOException e) {
/* We could not open the File for writing, or could not write to the File */
} finally {
try {
if (writer != null) {
writer.close(); // we are done writing to the File, close the connection
}
} catch (IOException e) {
/* We could not close the connection to the File */
}
}
}
/**
* Reads all lines from a File specified by filename
*
* #param filename The filename/path of the File we would like to read text from
*
* #return An list of Strings containing each line of the File
*/
public static List<String> readFromFile(String filename) {
BufferedReader reader = null; // This could go in a try-with-resources if you wanna get fancy
List<String> lines = new ArrayList<String>();
try {
reader = new BufferedReader(new FileReader(new File(filename))); // Open a File for writing
while ((line = reader.readLine()) != null) {
lines.add(line);
}
} catch (IOException e) {
/* We could not open the File for reading, or could not read from the File */
} finally {
try {
if (reader != null) {
reader.close(); // we are done reading from the File, close the connection
}
} catch (IOException e) {
/* We could not close the connection to the File */
}
}
return lines;
}
Write and read file on a swing thread is not recommanded. Use mvc pattern. Create a data model with field binded to your component. Create an adapter to update model and write file
Then your component will always up to date with your model
Use model to write data(with the adapter) and read file will update your model with the adapter
For exemple, Focus listener will call adapter to do the task. Or you can use an obseevee pattern when you Object if modified.
This code worked for me with 'nam' as the current date and 'name' an input in a jTextField.
try {
con=Connect.ConnectDB();
pst.execute();
Date date=new Date();
SimpleDateFormat sd=new SimpleDateFormat("dd-mm-yyyy-h-m-s");
String nam= sd.format(date);
String name=CaseNoField.getText();
CaseNoField.setText("");
FileWriter writer=new FileWriter( "C:\\path"+name+"("+nam+")"+".txt");
BufferedWriter bw=new BufferedWriter( writer );
JCaseArea.write( bw );
bw.close();
JCaseArea.setText("");
JCaseArea.requestFocus();
JOptionPane.showMessageDialog(null, "Case Saved");
}
catch(Exception e){
JOptionPane.showMessageDialog(null, e);
}