I tried to write a simple test program using Swing, all I want to do is load a text file and display the path of the chosen text file in a text area. I keep getting a warning on the process method "never used locally" and it is not appending any text to the textbox. Maybe I'm misunderstanding something, I hope someone can help me.
code:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.SwingWorker;
import javax.swing.filechooser.FileNameExtensionFilter;
public class MyPanel3 extends JPanel{
/**
*
*/
private static final long serialVersionUID = 1L;
private JTextArea jcomp;
private JButton btn;
private String testfile;
public MyPanel3() {
//construct components
jcomp = new JTextArea (1, 1);
jcomp.setBorder(BorderFactory.createDashedBorder(Color.BLACK));
btn = new JButton ("open");
//adjust size and set layout
setPreferredSize (new Dimension (944, 575));
BoxLayout layout = new BoxLayout (this, BoxLayout.Y_AXIS);
setLayout(layout);
//add main components
add (jcomp);
add (btn);
new SwingWorker<Void, String>(){
protected Void doInBackground(){
//do processes...
btn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
final JFileChooser chooseFile = new JFileChooser();
FileNameExtensionFilter filter = new FileNameExtensionFilter(".txt","txt");
chooseFile.setFileFilter(filter);
chooseFile.setAcceptAllFileFilterUsed(false);
chooseFile.setMultiSelectionEnabled(true);
if(ae.getSource().equals(btn))
{
System.out.println("do in background running");
int returnVal = chooseFile.showOpenDialog(MyPanel3.this);
if(returnVal == JFileChooser.APPROVE_OPTION)
{
File[] files = chooseFile.getSelectedFiles();
testfile = files[0].getPath();
publish(testfile);
}
}
}
});
return null;
}
protected void process(String s) {
jcomp.append(s);
}
protected void done() {
try
{
//System.out.println("The operation was completed");
}
catch (Exception e)
{
e.printStackTrace();
}
}
}.execute();
}
public static void main(String[] args){
JFrame frame = new JFrame ("MyTest");
frame.getContentPane();
frame.add(new MyPanel3());
frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible (true);
}
}
warning reads:
The method process(String) from the type new
SwingWorker(){} is never used locally
EDIT:
with help from MadProgrammer, program is now working (selecting 3 files and printing the paths as strings in the text box)
import java.awt.Color;
import java.awt.Dimension;
import java.util.ArrayList;
import java.util.List;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.SwingWorker;
import javax.swing.filechooser.FileNameExtensionFilter;
public class MyPanel4 extends JPanel {
/**
*
*/
private static final long serialVersionUID = 1L;
private JTextArea jcomp;
private JButton btn;
public MyPanel4() {
//construct components
jcomp = new JTextArea(1, 1);
jcomp.setBorder(BorderFactory.createDashedBorder(Color.BLACK));
btn = new JButton("open");
btn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
final JFileChooser chooseFile = new JFileChooser();
FileNameExtensionFilter filter = new FileNameExtensionFilter(".txt", "txt");
chooseFile.setFileFilter(filter);
chooseFile.setAcceptAllFileFilterUsed(false);
chooseFile.setMultiSelectionEnabled(true);
int returnVal = chooseFile.showOpenDialog(MyPanel4.this);
if (returnVal == JFileChooser.APPROVE_OPTION) {
final File[] files = chooseFile.getSelectedFiles();
new SwingWorker<Void, String>() {
private String testfile1 = files[0].getPath();
private String testfile2 = files[1].getPath();
private String testfile3 = files[2].getPath();
protected Void doInBackground() {
List<String> b = new ArrayList<String>();
b.add(testfile1);
b.add(testfile2);
b.add(testfile3);
publish(b.get(0));
publish(b.get(1));
publish(b.get(2));
return null;
}
#Override
protected void process(List<String> chunks) {
for (String pathname : chunks)
{
jcomp.append(pathname + "\n");
}
}
protected void done() {
try
{
System.out.println("Opration Completed");
} catch (Exception e) {
e.printStackTrace();
}
}
}.execute();
}
}
});
//adjust size and set layout
setPreferredSize(new Dimension(944, 575));
BoxLayout layout = new BoxLayout(this, BoxLayout.Y_AXIS);
setLayout(layout);
//add main components
add(jcomp);
add(btn);
}
public static void main(String[] args) {
JFrame frame = new JFrame("MyTest");
frame.getContentPane();
frame.add(new MyPanel4());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
}
The SwingWorker should be created inside the buttons actionPerformed method, so that when you click the button, it will run the SwingWorker
You should, also, make sure that all interactions with user interface are fine from within the context of the Event Dispatching Thread. This means you should ask the user to select the file fro within the context of the actionPerformed method and pass the result to the SwingWorked
Updated
Two additional things...
You're not actually reading the file, but simply passing the name of the file to the publish method
SwingWorker defines process as protected void process(List<V> chunks) but you've defined it as protected void process(String s)...mean that you are actually not overriding the SwingWorker's process method, but creating your own...
Take a look at this example to see how you might be able to use a SwingWorker to read a file...
And, update your process to have the corrected method signature...
#Override
protected void process(List<String> chunks) {
for (String line : chunks) {
output.append(line);
}
}
Remember, you should, as much as possible, use the #Override annotation when you think you are overriding a method, the compiler will tell you when you are mistaken, saving you a lot of head scratching...
It should be like this:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.SwingWorker;
import javax.swing.filechooser.FileNameExtensionFilter;
public class MyPanel3 extends JPanel {
/**
*
*/
private static final long serialVersionUID = 1L;
private JTextArea jcomp;
private JButton btn;
private String testfile;
public MyPanel3() {
//construct components
jcomp = new JTextArea(1, 1);
jcomp.setBorder(BorderFactory.createDashedBorder(Color.BLACK));
btn = new JButton("open");
btn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
final JFileChooser chooseFile = new JFileChooser();
FileNameExtensionFilter filter = new FileNameExtensionFilter(".txt", "txt");
chooseFile.setFileFilter(filter);
chooseFile.setAcceptAllFileFilterUsed(false);
chooseFile.setMultiSelectionEnabled(true);
int returnVal = chooseFile.showOpenDialog(MyPanel3.this);
if (returnVal == JFileChooser.APPROVE_OPTION) {
File[] files = chooseFile.getSelectedFiles();
testfile = files[0].getPath();
new SwingWorker<Void, String>() {
protected Void doInBackground() {
publish(testfile);
return null;
}
protected void process(String s) {
jcomp.append(s);
}
protected void done() {
try {
//System.out.println("The operation was completed");
} catch (Exception e) {
e.printStackTrace();
}
}
}.execute();
}
}
});
//adjust size and set layout
setPreferredSize(new Dimension(944, 575));
BoxLayout layout = new BoxLayout(this, BoxLayout.Y_AXIS);
setLayout(layout);
//add main components
add(jcomp);
add(btn);
}
public static void main(String[] args) {
JFrame frame = new JFrame("MyTest");
frame.getContentPane();
frame.add(new MyPanel3());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
}
You are running worker when you are creating panel. But you should run it when button is clicked.
Related
I am creating a user interface for a pdf reader, and I want to have a list with recent open files. (Not the content of the files, just the name of the file).
From the snap shared, I assume that you are using JFileChooser for your dialog to open file. Hope this helps!
int result = fileChooser.showOpenDialog(panel);
//where panel is an instance of a Component such as JFrame, JDialog or JPanelwhich is parent of the dialog.
if (result == JFileChooser.APPROVE_OPTION) {
File selectedFile = fileChooser.getSelectedFile();
textArea.setText(selectedFile.getName());
}
The example below uses a JFileChooser with setMultiSelectionEnabled(true) to add() one or more files to a List<File> and update() a JTextArea with the current list. As suggested here, you can use Action to maintain a menu or tool bar of recent files.
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.swing.AbstractAction;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
/**
* #see https://stackoverflow.com/a/37153404/230513
* #see https://stackoverflow.com/a/4039359/230513
*/
public class Test {
private final List<File> recentFiles = new ArrayList<>();
private final JTextArea textArea = new JTextArea(12, 12);
private void display() {
JFrame f = new JFrame("Test");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
textArea.setBorder(BorderFactory.createTitledBorder("Recent Files"));
f.add(textArea);
JPanel p = new JPanel(new FlowLayout(FlowLayout.RIGHT));
p.add(new JButton(new AbstractAction("Open") {
#Override
public void actionPerformed(ActionEvent e) {
JFileChooser jfc = new JFileChooser(".");
jfc.setMultiSelectionEnabled(true);
if (jfc.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
recentFiles.addAll(Arrays.asList(jfc.getSelectedFiles()));
update();
}
}
}));
f.add(p, BorderLayout.SOUTH);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
private void update() {
textArea.setText("");
for (File file : recentFiles) {
textArea.append(file.getName() + "\n");
}
}
public static void main(String[] args) {
EventQueue.invokeLater(new Test()::display);
}
}
I'd like to create a Java Swing Photo Album but I can't manage to find the right way to do it. I think it should be to create two ArrayList, one to stock the photo objects and another one to stock the buttons.
After that I should find a way to assign each images to the buttons and add them into the panel.
My question is : Do you think it is the right way to do it and if so, could you give me a hint? (For the last class at the bottom)
Here's my code at the moment :
Main :
import javax.swing.JFrame;
public class Main extends JFrame {
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
new AlbumFrame();
}
});
}
}
AlbumFrame :
import java.awt.BorderLayout;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class AlbumFrame extends JFrame {
private JPanel MenuPanel;
private JPanel PhotoPanel;
public AlbumFrame(){
super("JPhone");
setLayout(new BorderLayout());
PhotoPanel = new PhotoPanel();
add(PhotoPanel,BorderLayout.CENTER);
MenuPanel = new MenuPanel();
add(MenuPanel,BorderLayout.SOUTH);
setSize(480,800);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
}
MenuPanel
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JPanel;
import javax.swing.filechooser.FileNameExtensionFilter;
public class MenuPanel extends JPanel implements ActionListener{
private static final long serialVersionUID = 1L;
private JButton backButton;
private JButton homeButton;
private JButton turnButton;
private JButton addButton;
final private JFileChooser fc;
public MenuPanel(){
fc = new JFileChooser();
backButton = new JButton(new ImageIcon(getClass().getResource("/Images/back.png")));
homeButton = new JButton(new ImageIcon(getClass().getResource("/Images/home.png")));
turnButton = new JButton(new ImageIcon(getClass().getResource("/Images/turn.png")));
addButton = new JButton(new ImageIcon(getClass().getResource("/Images/add.png")));
backButton.setPreferredSize(new Dimension(55,55));
homeButton.setPreferredSize(new Dimension(55,55));
turnButton.setPreferredSize(new Dimension(55,55));
addButton.setPreferredSize(new Dimension(55,55));
backButton.addActionListener(this);
homeButton.addActionListener(this);
turnButton.addActionListener(this);
addButton.addActionListener(this);
setLayout(new FlowLayout(FlowLayout.CENTER));
add(backButton);
add(homeButton);
add(turnButton);
add(addButton);
}
public void actionPerformed(ActionEvent e) {
JButton clicked = (JButton)e.getSource();
//Test for the moment
if(clicked == backButton){
System.out.println("back");
}else if(clicked == homeButton){
System.out.println("home");
}else if(clicked == turnButton){
System.out.println("turn");
}else if(clicked == addButton){
int returnVal = fc.showOpenDialog(MenuPanel.this);
if(returnVal == JFileChooser.APPROVE_OPTION){
File file = fc.getSelectedFile();
}
}
}
}
PhotoPanel
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import javax.swing.JButton;
import javax.swing.JPanel;
public class PhotoPanel extends JPanel implements ActionListener {
ArrayList<Photo> Album = new ArrayList<Photo>();
ArrayList<JButton> Buttons = new ArrayList<JButton>();
public PhotoPanel(){
setLayout(new FlowLayout(FlowLayout.CENTER));
}
public void actionPerformed(ActionEvent e) {
}
}
I would use separate class like PhotoCard to avoid lists:
class PhotoCard {
public PhotoCard(Photo photo) {
add(photo);
// also add buttons, listeners, etc.
}
}
that holds necessary data and initializes listeners.
And then class can be added to to your PhotoPanel:
PhotoPanel.add(new PhotoCard(...));
I minimized my program to include only the problem and I tried to code exactly as I understood from many examples. When I used the ActionListener, I get problem solved. But I wonder why using ItemListener, checkbox does not operate correctly.
If I run my program without ItemListener, it works correctly. With this ItemListener, checkBox doesn't change state.
import java.awt.FlowLayout;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
public class omaJFrame extends JFrame{
private JCheckBox checkBox1;
public omaJFrame() {
super("Window Title");
TheHandler handler = new TheHandler();
setLayout(new FlowLayout());
checkBox1 = new JCheckBox("Checkbox 1");
add(checkBox1);
checkBox1.addItemListener(handler);
}
private class TheHandler implements ItemListener {
String output = "";
public void itemStateChanged(ItemEvent event) {
if (event.getItem()==checkBox1)
output = String.format("%s", checkBox1.isSelected());
JOptionPane.showMessageDialog(null, output);
}
}
}
import javax.swing.JFrame;
public class EventHandlerMain {
public static void main(String[] args) {
omaJFrame window = new omaJFrame();
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setSize(350,200);
window.setVisible(true);
}
}
Works for me. Note also that Swing GUI objects should be constructed and manipulated only on the event dispatch thread.
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
public class OmaJFrame extends JFrame {
private JCheckBox checkBox1;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
OmaJFrame f = new OmaJFrame();
}
});
}
public OmaJFrame() {
super("Window Title");
setDefaultCloseOperation(EXIT_ON_CLOSE);
TheHandler handler = new TheHandler();
setLayout(new FlowLayout());
checkBox1 = new JCheckBox("Checkbox 1");
add(checkBox1);
checkBox1.addItemListener(handler);
pack();
setLocationByPlatform(true);
setVisible(true);
}
private class TheHandler implements ItemListener {
String output = "";
#Override
public void itemStateChanged(ItemEvent event) {
if (event.getItem() == checkBox1) {
output = String.format("%s", checkBox1.isSelected());
}
JOptionPane.showMessageDialog(null, output);
}
}
}
Calling one JFrame from another using Timer without any buttons: time is decreased then open another JFrame without any buttons. Please help. Used in netbeans
Your question is very unclear, but the use of multiple frames is not recommended. As an alternative, consider a modeless dialog, shown below. The dialog's enclosed JOptionPane listens for a PropertyChangeEvent, while counting down from TIME_OUT using javax.swing.Timer. The JOptionPane button is convenient but not required.
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.Timer;
/**
* #see https://stackoverflow.com/a/12451673/230513
*/
public class JOptionTimeTest implements ActionListener, PropertyChangeListener {
private static final int TIME_OUT = 10;
private int count = TIME_OUT;
private final Timer timer = new Timer(1000, this);
private JDialog dialog = new JDialog();
private final JOptionPane optPane = new JOptionPane();
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
new JOptionTimeTest().createGUI();
}
});
}
private void createGUI() {
JFrame frame = new JFrame("Title");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
timer.setCoalesce(false);
optPane.setMessage(message());
optPane.setMessageType(JOptionPane.INFORMATION_MESSAGE);
optPane.setOptionType(JOptionPane.DEFAULT_OPTION);
optPane.addPropertyChangeListener(this);
dialog.add(optPane);
dialog.pack();
frame.add(new JLabel(frame.getTitle(), JLabel.CENTER));
frame.pack();
frame.setVisible(true);
dialog.setLocationRelativeTo(frame);
dialog.setVisible(true);
timer.start();
}
public void propertyChange(PropertyChangeEvent e) {
String prop = e.getPropertyName();
if (JOptionPane.VALUE_PROPERTY.equals(prop)) {
thatsAllFolks();
}
}
public void actionPerformed(ActionEvent e) {
count--;
optPane.setMessage(message());
if (count == 0) {
thatsAllFolks();
}
timer.restart();
}
private String message() {
return "Closing in " + count + " seconds.";
}
private void thatsAllFolks() {
dialog.setVisible(false);
dialog.dispatchEvent(new WindowEvent(
dialog, WindowEvent.WINDOW_CLOSING));
}
}
Im trying to display an image upon clicking a JButton but upon execution the image is not displayed when button is clicked.
import javax.swing.JButton;
import javax.swing.JFrame;
import java.awt.Color;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.Graphics;
import java.awt.Image;
import javax.swing.ImageIcon;
import javax.swing.JApplet;
import java.awt.*;
public class new2 extends JFrame implements ActionListener
{
private boolean b1,b2;
Container contentPane= getContentPane();
JButton awar=new JButton("#war");
JButton arrow=new JButton("arrow");
private Image image1,image2;
public new2()
{
setSize(400, 300);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
contentPane.setLayout(new FlowLayout());
awar.addActionListener(this);
contentPane.add(awar).setVisible(true);
arrow.addActionListener(this);
contentPane.add(arrow).setVisible(true);
}
public void init()
{
image1=Toolkit.getDefaultToolkit().getImage("#war.jpeg");
image2=Toolkit.getDefaultToolkit().getImage("arrow.gif");
}
public void paint(Graphics g)
{
if(b1==true)
{
g.drawImage(image1,0,0,this);
}
else if(b2==true)
{
g.drawImage(image2,0,0,this);
}
}
public void actionPerformed(ActionEvent event)
{
String actionCommand = event.getActionCommand();
if(actionCommand.equals("#war"))
{
b1=true;
}
else if(actionCommand.equals("arrow"))
{
b2=true;
}
}
public static void main(String args[])
{
new2 m=new new2();
m.setVisible(true);
}
}
..display an image upon clicking a JButton but upon execution the image is not displayed when button is clicked.
Use a JToggleButton as shown here.
The buttons should set the boolean variables, but your paint2 is never called after the action preformed method. Secondly, it doesn't really even paint anything, it never gets graphics and will cause NPEs.
You should override the JFrame.paint(Graphics g) method.
Whenever you want to refresh the content of the JFrame instance call the JFrame.repaint() method.
/**
*
*/
package com.samples;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.WindowConstants;
/**
* #author
*
*/
public class MyFrame extends JFrame implements ActionListener {
private static String SHOW_ACTION = "show";
private static String HIDE_ACTION = "hide";
private Image image = null;
private boolean showImage = false;
public MyFrame(String filename) {
setTitle("MyWindow");
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setSize(800, 600);
this.image = new ImageIcon(filename).getImage();
Container container = getContentPane();
container.setLayout(new BorderLayout());
container.add(createControls(), BorderLayout.SOUTH);
}
private JPanel createControls() {
JButton showButton = new JButton("Show");
showButton.addActionListener(this);
showButton.setActionCommand(SHOW_ACTION);
JButton hideButton = new JButton("Hide");
hideButton.addActionListener(this);
hideButton.setActionCommand(HIDE_ACTION);
JPanel panel = new JPanel();
panel.setLayout(new FlowLayout(FlowLayout.CENTER));
panel.add(showButton);
panel.add(hideButton);
return panel;
}
#Override
public void paint(Graphics g) {
super.paint(g);
if (showImage) {
g.drawImage(image, 0, 0, image.getWidth(null), image.getHeight(null), null);
}
}
#Override
public void actionPerformed(ActionEvent event) {
String actionCommand = event.getActionCommand();
if (SHOW_ACTION.equals(actionCommand)) {
showImage = true;
} else if (HIDE_ACTION.equals(actionCommand)) {
showImage = false;
}
repaint();
}
/**
* #param args
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
MyFrame frame = new MyFrame("resources/image.jpg");
frame.setVisible(true);
}
});
}
}