I am working on a little project and want to display the Name of the opened File.
The problem is, the JLabel who should display the File Name is not repainting, I had read that it should be repainted by itself..
here is my code for the FileChooser and to get the File Name ( I know that i get the path of the file, I will format it later..
/**
* Opens a window where the user can select a file.
*
* #return Scanner in
*/
public Scanner openFile() {
JFileChooser chooser = new JFileChooser();
Scanner in = null;
if (chooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
File selectedInFile = chooser.getSelectedFile();
try {
absolutePathOfFile = selectedInFile.getAbsolutePath();
FileReader fileReader = new FileReader(selectedInFile.getAbsolutePath());
in = new Scanner(fileReader);
} catch (FileNotFoundException ex) {
// File not found
System.out.println("File not found!!");
}
}
return in;
}
public List getList() {
return listOfEveryVariable;
}
#Override
public String getFileName() {
return absolutePathOfFile;
}
And here is the code for my Label
public Component createInfoPanel() {
infoPanel = new JPanel(new BorderLayout());
infoPanel.setBackground(Color.LIGHT_GRAY);
fileInfoPanel = new JPanel(new GridLayout(1,2));
fileInfoPanel.setBackground(Color.LIGHT_GRAY);
infoPanel.add(fileInfoPanel, BorderLayout.WEST);
JLabel fileInfo_1 = new JLabel();
fileInfo_1.setText("File: ");
fileInfoPanel.add(fileInfo_1);
JLabel fileInfo_2 = new JLabel();
FileName fn = new Datahandler();
fileInfo_2.setText(fn.getFileName());
fileInfoPanel.add(fileInfo_2);
return infoPanel;
}
The GuiInfoPanel is created and added in and to an Frame..
If I set a name to the getFileName() class and let it return it works and the name is displayed.
Greetings
The createInfoPanel is called here:
public class GuiFrame extends JFrame {
private static final int FRAME_WIDTH = 800;
private static final int FRAME_HIGHT = 600;
/**
* The variables for the panels
*/
private JPanel mainPanel, menuPanel, plotPanel, scatterplotPanel,
histogramPanel, histogram1, histogram2;
public GuiFrame() {
setSize(FRAME_WIDTH, FRAME_HIGHT);
/**
* Create Objects
*/
GuiMenuBar mb = new GuiMenuBar();
GuiInfoPanel ip = new GuiInfoPanel();
GuiOptionPanel op = new GuiOptionPanel();
JComponent sp = new Scatterplot();
/**
* Create Panels
*/
createMainPanel();
mb.createMenuBar();
ip.createInfoPanel();
op.createOptionPanel();
/**
* Add Panels
*/
this.add(mainPanel);
this.setJMenuBar(mb);
this.add(ip.infoPanel, BorderLayout.SOUTH);
menuPanel.add(op.optionPanel, BorderLayout.NORTH);
scatterplotPanel.add(sp, BorderLayout.CENTER);
}
private Component createMainPanel(){
mainPanel = new JPanel(new BorderLayout());
menuPanel = new JPanel(new BorderLayout());
mainPanel.add(menuPanel, BorderLayout.WEST);
plotPanel = new JPanel(new GridLayout(2,1));
plotPanel.setBorder(BorderFactory.createLineBorder(Color.black));
mainPanel.add(plotPanel, BorderLayout.CENTER);
scatterplotPanel = new JPanel(new BorderLayout());
scatterplotPanel.setBorder(BorderFactory.createLineBorder(Color.black));
plotPanel.add(scatterplotPanel);
histogramPanel = new JPanel(new GridLayout(1,2));
plotPanel.add(histogramPanel);
histogram1 = new JPanel(new BorderLayout());
histogram1.setBorder(BorderFactory.createLineBorder(Color.black));
histogramPanel.add(histogram1);
histogram2 = new JPanel(new BorderLayout());
histogram2.setBorder(BorderFactory.createLineBorder(Color.black));
histogramPanel.add(histogram2);
return mainPanel;
}
}
I think that the panel being called only once is be the problem.
It looks like the problem is that createInfoPanel() is only ever called once, at the point where you create the screen. At this point, setText() is doing what you'd expect it to, but the user hasn't chosen a file yet. I am basing this on the fact that if createInfoPanel() were called multiple times, you would end up adding more labels to the screen than desired.
When you select a file from your file chooser, createInfoPanel() doesn't magically get called again and so the text never gets updated on the JLabel. It would be useful to see the code that calls createInfoPanel() and the code that calls openFile() to verify this is the case.
Regarding your second question - you can't reference the JLabel outside of where it is declared. As you are declaring the JLabel within createInfoPanel() it is a local variable to this method only. If you want it to be accessed by other methods you need to make it a class variable, similar to the "absolutePathOfFile" variable. So you might do something like:
public class GuiInfoPanel {
private final JPanel infoPanel;
private final JLabel fileInfo = new JLabel();
public Component createInfoPanel() {
infoPanel = new JPanel(new BorderLayout());
infoPanel.setBackground(Color.LIGHT_GRAY);
fileInfo.setText("File: ");
infoPanel.add(fileInfo, BorderLayout.WEST);
return infoPanel;
}
/**
* Call this whenever the user picks a new file
*/
public void setFileInfoText(String filePath){
fileInfo.setText("File: " + filePath);
}
}
EDIT: Your latest code confirms my suspicions - createInfoPanel() is only called by the constructor, so will only be called once. Try something like my code snippet above to get the behaviour you're after. And a side-note: You should edit your original post to include more information rather than posting updates as 'answers'!
EDIT 2: See below for a self-contained 'toy' example that should help you to get the behaviour you're after.
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class FileSelectionDemo extends JFrame
implements ActionListener
{
public static void main(String[] args)
{
FileSelectionDemo demoScreen = new FileSelectionDemo();
demoScreen.setSize(300, 300);
demoScreen.setVisible(true);
}
public FileSelectionDemo()
{
getContentPane().setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
getContentPane().add(btnSelectFile);
getContentPane().add(lblFilePath);
btnSelectFile.addActionListener(this);
}
private final JLabel lblFilePath = new JLabel("");
private final JButton btnSelectFile = new JButton("Choose File");
public void selectFile()
{
JFileChooser chooser = new JFileChooser();
if (chooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION)
{
File selectedInFile = chooser.getSelectedFile();
String absolutePathOfFile = selectedInFile.getAbsolutePath();
lblFilePath.setText(absolutePathOfFile);
}
}
#Override
public void actionPerformed(ActionEvent arg0)
{
Object source = arg0.getSource();
if (source == btnSelectFile)
{
selectFile();
}
}
}
Related
I am trying to create and Editable JComboBox to allow the user to type the name of the song to purchase. However when I set tunes.setEditable(true); I get an error... any help will be appreciated!
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.JTextArea;
public class JTunes2 extends JFrame implements ItemListener
{
int songNum,songPrice;
int[] songAmount = {2,5,8,1,4,7,12,10,11,3,6,9};
String result;
JComboBox tunes = new JComboBox();
// set as editable
tunes.setEditable(true);
JLabel labelTunes = new JLabel("Song List");
JLabel outputs = new JLabel();
FlowLayout layout = new FlowLayout();
public JTunes2()
{
super("Song Selector");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
panel.setLayout(layout);
// add song names to combo box and register an item listener.
tunes.addItem("Song1");
tunes.addItem("Song2");
tunes.addItem("Song3");
tunes.addItem("Song4");
tunes.addItem("Song5");
tunes.addItem("Song6");
tunes.addItem("Song7");
tunes.addItem("Song8");
tunes.addItem("Song9");
tunes.addItem("Song10");
tunes.addItem("Song11");
tunes.addItem("Song12");
tunes.addItemListener(this);
panel.add(labelTunes);
panel.add(tunes);
panel.add(outputs);
//add panel to the frame
setContentPane(panel);
}
public void itemStateChanged(ItemEvent e)
{
//create source object
Object source = e.getSource();
//check the type size
if(source == tunes)
{
songNum = tunes.getSelectedIndex();
songPrice = songAmount[songNum];
result = "Total Price $" + songPrice;
//Display result
outputs.setText(result);
}
}
public static void main(String[] args)
{
// create class object
JTunes frame = new JTunes();
frame.setSize(250, 180);
frame.setVisible(true);
}
}
Thank you!
Actually, Java requires that you setup JComponents in the constructor. In order for your code to work, you need to call on setEditable(true) in the constructor, which means that you just need to move tunes.setEditable(true); to the constructor.
Tip: always allocate memory for JComponents in the constructor (you want to draw the components as soon as you create the Jframe). You can have a reference to the JComboBox at the class level.
Here is another version of your code:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.JTextArea;
public class JTunes2 extends JFrame implements ItemListener
{
int songNum,songPrice;
int[] songAmount = {2,5,8,1,4,7,12,10,11,3,6,9};
String result;
JComboBox tunes;
JLabel labelTunes = new JLabel("Song List");
JLabel outputs = new JLabel();
FlowLayout layout = new FlowLayout();
public JTunes2()
{
super("Song Selector");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
panel.setLayout(layout);
tunes = new JComboBox();
// set as editable
tunes.setEditable(true);
// add song names to combo box and register an item listener.
tunes.addItem("Song1");
tunes.addItem("Song2");
tunes.addItem("Song3");
tunes.addItem("Song4");
tunes.addItem("Song5");
tunes.addItem("Song6");
tunes.addItem("Song7");
tunes.addItem("Song8");
tunes.addItem("Song9");
tunes.addItem("Song10");
tunes.addItem("Song11");
tunes.addItem("Song12");
tunes.addItemListener(this);
panel.add(labelTunes);
panel.add(tunes);
panel.add(outputs);
//add panel to the frame
setContentPane(panel);
}
public void itemStateChanged(ItemEvent e)
{
//create source object
Object source = e.getSource();
//check the type size
if(source == tunes)
{
songNum = tunes.getSelectedIndex();
songPrice = songAmount[songNum];
result = "Total Price $" + songPrice;
//Display result
outputs.setText(result);
}
}
public static void main(String[] args)
{
// create class object
JTunes2 frame = new JTunes2();
frame.setSize(250, 180);
frame.setVisible(true);
}
}
You added the tunes.setEditable(true) at the class level, instead of at the method level. No statements allowed at the class level!
Here's a fixed version: I renamed JTunes2 to JTunes to fix the compilation errors, and moved the setEditable to the constructor. Also I fixed the indentation - this makes it harder to make this mistake:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.JTextArea;
public class JTunes extends JFrame implements ItemListener
{
int songNum,songPrice;
int[] songAmount = {2,5,8,1,4,7,12,10,11,3,6,9};
String result;
JComboBox tunes = new JComboBox();
JLabel labelTunes = new JLabel("Song List");
JLabel outputs = new JLabel();
FlowLayout layout = new FlowLayout();
public JTunes()
{
super("Song Selector");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
panel.setLayout(layout);
tunes.setEditable(true);
// add song names to combo box and register an item listener.
tunes.addItem("Song1");
tunes.addItem("Song2");
tunes.addItem("Song3");
tunes.addItem("Song4");
tunes.addItem("Song5");
tunes.addItem("Song6");
tunes.addItem("Song7");
tunes.addItem("Song8");
tunes.addItem("Song9");
tunes.addItem("Song10");
tunes.addItem("Song11");
tunes.addItem("Song12");
tunes.addItemListener(this);
panel.add(labelTunes);
panel.add(tunes);
panel.add(outputs);
//add panel to the frame
setContentPane(panel);
}
public void itemStateChanged(ItemEvent e)
{
//create source object
Object source = e.getSource();
//check the type size
if(source == tunes)
{
songNum = tunes.getSelectedIndex();
songPrice = songAmount[songNum];
result = "Total Price $" + songPrice;
//Display result
outputs.setText(result);
}
}
public static void main(String[] args)
{
// create class object
JTunes frame = new JTunes();
frame.setSize(250, 180);
frame.setVisible(true);
}
}
In my software I am using card layout to create a "wizard-based" interface. In panel, user chooses a file, in the other one get information regarding the chosen file in previous panel.
The problem is that CardLayout loads all panels all together. So panels deals with predefined data. But I would like to update the next panel with the information given in the current panel.
each panel has 'next' and 'back' buttons, so I think that is the point where next panels can get updated somehow. I thought using setters and getters methods but could not implement it correctly.
Here is a sample code with two sub-panels:
BASE CLASS:
public Base(){
frame.setLayout(bl);
frame.setSize(800, 600);
frame.add(new MainPanel(), BorderLayout.CENTER);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
public static void main(String[] args) {
// TODO code application logic here
new Base();
}
}
MainPanel (sub-panels holder)
class MainPanel extends JPanel{
private CardLayout cl = new CardLayout();
private JPanel panelHolder = new JPanel(cl);
public MainPanel() {
ChooseFile chooseFile = new ChooseFile(this);
ShowResult showResult = new ShowResult(this);
panelHolder.add(showResult, "showResult");
panelHolder.add(chooseFile, "chooseFile");
cl.show(panelHolder, "chooseFile");
add(panelHolder);
}
public void showPanel(String panelIdentifier){
cl.show(panelHolder, panelIdentifier);
}
}
Sub-Panel 1:
class ChooseFile extends JPanel{
MainPanel ob2;
JPanel directoryChooserPanel, bottomPanel;
JButton btn, localSourceBack, localSourceNext;
JTextField field;
public ChooseFile(MainPanel mainPanel){
this.ob2 = mainPanel;
ShowResult showResult = new ShowResult();
setLayout(new BorderLayout());
directoryChooserPanel = new JPanel(new GridLayout(0,2));
btn = new JButton("Browse");
btn.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e){
JFileChooser chooser = new JFileChooser("D:\\Desktop");
chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
int returnVal = chooser.showOpenDialog(null);
if(returnVal == JFileChooser.APPROVE_OPTION){
File myFile = chooser.getSelectedFile();
String text = myFile + "";
field.setText(text);
}
}
});
directoryChooserPanel.add(btn);
field = new JTextField(20);
directoryChooserPanel.add(field);
localSourceNext = new JButton("Next");
localSourceNext.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e){
ob2.showPanel("showResult");
showResult.setRoot(getPath());
}
});
add(directoryChooserPanel, BorderLayout.NORTH);
add(localSourceNext, BorderLayout.EAST);
}
public String getPath(){
return field.getText();
}
}
Sub Panel 2:
class ShowResult extends JPanel{
MainPanel ob2;
JPanel bottomPanel, labelsPanel;
JButton srcLocalBTN, srcFtpBTN, sourceLocationBack;
JLabel result;
File directory;
String root;
ArrayList<String> myFiles = new ArrayList<String>();
public ShowResult(MainPanel mainPanel){
this.ob2 = mainPanel;
setLayout(new BorderLayout());
result = new JLabel();
root = "No ADDRESS";
directory = new File(root);
listFiles(directory, myFiles);
String filesNumber = "It contains " + myFiles.size() + " files.";
result.setText(filesNumber);
add(result, BorderLayout.NORTH);
}
public void listFiles(File directory, ArrayList<String> list){
for(File file : directory.listFiles()){
list.add(file.getName());
if(file.isDirectory()){
listFiles(file.getAbsoluteFile(), list);
}
}
}
public ShowResult(){
}
public void setRoot(String chosenPath){
root = chosenPath;
}
}
So it firsts loads 'sub panel 1' so user chooses a directory by jFileChooser and then I need to transfer this data to 'sub panel 2'. So it can calculate how many files it is containing.
I tried to transfer data by getting the chosen directory and assigning to a variable in the second variable. But doesn't work.
Any idea?
You're creating more than one ShowResult object, displaying one but then passing information to the other, the non-displayed one, but this is not how Java works (this is easy to discover by simply searching this page for number of new ShowResult() matches). You need to be sure that the ShowResult object that is displayed is the exact same as the one you pass information to, meaning you'll have to pass the reference of the displayed object into your ChooseFile class via a constructor or method parameter.
Better option: use an MVC design pattern, make, have your controls change the state of the model and your views display the state of your model. This may reduce the cyclomatic complexity of your code.
I am writing a small program that converts files, and I wanted to have a box pop up that asks the user to please wait while the program loops through and converts all the relevant files, but I am running into a small problem. The box that pops up should have a JLabel and a JButton, while the user is "waiting" I wanted to display a message that says please wait, and a disabled "OK" JButton, and then when its finished I wanted to set the text of the JLabel to let them know that It successfully converted their files, and give them a count of how many files were converted. (I wrote a method called alert that sets the text of the label and enables the button.) The problem is That while the program is running, the box is empty, the Label and the Button are not visible, when it finishes, label appears with the final text that I want and the button appears enabled. I am not sure exactly what is going on, I tried changing the modifiers of the JLabel and JButton several times but I cant seem to get it to work correctly. Here is the code for the box that pops up, any help is greatly appricated.
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class PleaseWait extends javax.swing.JFrame{
private static final int height = 125;
private static final int width = 350;
final static JLabel converting = new JLabel("Please Wait while I convert your files");
private static JButton OK = new JButton("OK");
public PleaseWait(){
// creates the main window //
JFrame mainWindow = new JFrame();
mainWindow.setTitle("Chill For A Sec");
mainWindow.setSize(width, height);
mainWindow.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
// creates the layouts//
JPanel mainLayout = new JPanel(new BorderLayout());
JPanel textLayout = new JPanel(new FlowLayout());
JPanel buttonLayout = new JPanel(new FlowLayout());
// Sets Text //
converting.setText("Please wait while I convert your files");
// disables button //
OK.setEnabled(false);
// adds to the layouts //
textLayout.add(converting);
buttonLayout.add(OK);
mainLayout.add(textLayout, BorderLayout.CENTER);
mainLayout.add(buttonLayout, BorderLayout.SOUTH);
// adds to the frame //
mainWindow.add(mainLayout);
// sets everything visible //
mainWindow.setVisible(true);
}
public static void alert(){
OK.setEnabled(true);
String total = String.valueOf(Convert.result());
converting.setText("Sucsess! " + total + " files Converted");
}
}
Okay here's the issue. You are extending the JFrame . That means your class IS a JFrame.
When you create the PleaseWait frame you don't do anything to it. This is the empty box you are seeing. You are instead creating a different JFrame in your constructor. Remove your mainWindow and instead just use this. Now all of your components will be added to your PleaseWait object. That should fix your blank box issue.
You need an application to create your frame first. This is a simple example of such application.
import javax.swing.UIManager;
import java.awt.*;
public class Application {
boolean packFrame = false;
//Construct the application
public Application() {
PleaseWait frame = new PleaseWait();
//Validate frames that have preset sizes
//Pack frames that have useful preferred size info, e.g. from their layout
if (packFrame) {
frame.pack();
}
else {
frame.validate();
}
//Center the window
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
Dimension frameSize = frame.getSize();
if (frameSize.height > screenSize.height) {
frameSize.height = screenSize.height;
}
if (frameSize.width > screenSize.width) {
frameSize.width = screenSize.width;
}
frame.setLocation((screenSize.width - frameSize.width) / 2, (screenSize.height - frameSize.height) / 2);
frame.setVisible(true);
frame.convert();
}
//Main method
public static void main(String[] args) {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}
catch(Exception e) {
e.printStackTrace();
}
new Application();
}
}
You have to slightly modify your frame to add controls to the content pane. You can do some work after frame is created, then call alert.
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class PleaseWait extends JFrame {
private static final int height = 125;
private static final int width = 350;
final static JLabel converting = new JLabel();
private static JButton OK = new JButton("OK");
BorderLayout borderLayout1 = new BorderLayout();
JPanel contentPane;
int count;
public PleaseWait(){
contentPane = (JPanel)this.getContentPane();
contentPane.setLayout(borderLayout1);
this.setSize(new Dimension(width, height));
this.setTitle("Chill For A Sec");
this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
// creates the layouts//
JPanel mainLayout = new JPanel(new BorderLayout());
JPanel textLayout = new JPanel(new FlowLayout());
JPanel buttonLayout = new JPanel(new FlowLayout());
// Sets Text //
converting.setText("Please wait while I convert your files");
// disables button //
OK.setEnabled(false);
OK.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
// adds to the layouts //
textLayout.add(converting);
buttonLayout.add(OK);
mainLayout.add(textLayout, BorderLayout.CENTER);
mainLayout.add(buttonLayout, BorderLayout.SOUTH);
// adds to the frame //
contentPane.add(mainLayout);
}
public void convert(){
count = 0;
for (int i = 0; i <10; i++){
System.out.println("Copy "+i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
count++;
}
alert();
}
public void alert(){
OK.setEnabled(true);
// String total = String.valueOf(Convert.result());
converting.setText("Sucsess! " + count + " files Converted");
}
}
I have this method to print and set the material properties of a Solid Object in a class called MaterialProperties, which has printMaterial & setMaterial methods.
public void Btn3_callback ( ) throws Exception {
Model model = session.GetCurrentModel();
if (model == null) {
mesg = "No Model Selected!!";
//TextField.Area("No Model Selected!!");
System.exit(0);
}
else {
Solid solid= (Solid) model;
String newMaterial="copper";//user input for new Material name
printMaterial(solid);//printMaterial print the Material properties of the Solid object
setMaterial(solid,newMaterial);//setMaterial sets the Material properties of the Solid object to the material entered
}
}
I need to get the user input for newMaterial instead of hard coding it. What I need to do is to display all the Material types avaialable, so that the user can just select the material required. So I tried to do this using JFrame. Here's the code I have:
public class MaterialWindow {
JFrame frame = new JFrame("Material Selection");
public MaterialWindow(){
// Directory path here
String path = "W:\\materials";
JFrame frame = new JFrame("Material Selection");
JPanel panel = new JPanel(new GridLayout(0, 4));
ButtonGroup bg = new ButtonGroup();
String files;
File folder = new File(path);
File[] listOfFiles = folder.listFiles();
JRadioButton button;
for (int i = 0; i < listOfFiles.length; i++)
{
if (listOfFiles[i].isFile())
{
files = listOfFiles[i].getName();
if (files.endsWith(".mtl") || files.endsWith(".MTL"))
{
button = new JRadioButton(files);
panel.add(first,BorderLayout.CENTER);
panel.revalidate();
bg.add(button);
first.addActionListener(new MyAction());
}
}
}
frame.add(panel, BorderLayout.NORTH);
frame.getContentPane().add(new JScrollPane(panel), BorderLayout.CENTER);
frame.setSize(1000, 400);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public class MyAction implements ActionListener{
public void actionPerformed(ActionEvent e){
String newMaterial =e.getActionCommand();
String[] split = newMaterial.split("\\.");
newMaterial = split[0];
newMaterial.trim();
//set the newMaterial for btn3_callback OR call the setMaterial method of MaterialPropeties class
frame.dispose();
}
}
}
Now the problem is how can I use the newMaterial string selected from the radio button to newMaterial in my Btn3_callback() function? When I create a getString() method for newMaterial in the class MyAction and use that it Btn3_callback it always returns null;
Is there any way I can do this? Or any different way I can implement the idea?
Thanks
Use a JOptionPane instead of the frame. Put a list (JList ..or JComboBox) of options in the option pane and query the component once returned (the pane is closed), for the selected object.
E.G. using JComboBox
The GUI should be created and altered on the EDT (batteries not included).
import java.io.File;
import javax.swing.*;
public class QuickTest {
public static void main(String[] args) throws Exception {
File[] files = new File(System.getProperty("user.home")).listFiles();
JFrame f = new JFrame("Faux J-Link");
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JEditorPane jep = new JEditorPane();
f.add(new JScrollPane(jep));
f.setSize(600,400);
f.setLocationByPlatform(true);
f.setVisible(true);
JComboBox choices = new JComboBox(files);
int result = JOptionPane.showConfirmDialog(f, choices);
if (result==JOptionPane.OK_OPTION) {
System.out.println("OK");
File file = files[choices.getSelectedIndex()];
jep.setPage(file.toURI().toURL());
}
}
}
I want to change the image a JLabel is viewing during runtime, but I keep getting NullPointerExceptions or nothing happens when I press the magic button that's supposed to do things. Is it even possible in Java?
Here is my code in its entirety:
import java.text.*;
import javax.swing.text.*;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
public class Shell implements ActionListener, MenuKeyListener
{
JFrame frame;
JWindow window;
JButton PSubmit;
JPanel pane1, pane2;
JRadioButton R1, R2, R3;
ButtonGroup PGroup;
JTabbedPane layout;
String result;
String border = "Border.png";
String DF = "Frame.png";
String list [];
Driver driver;
public Shell()
{
driver = new Driver();
list = new String [6];
}
public void setFrame()
{
frame = new JFrame("Pokemon Program 3 by Systems Ready");
frame.setSize(600, 600);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.getContentPane().setLayout(new BorderLayout());
}
public void frameLayout()
{
layout = new JTabbedPane();
JPanel pane1 = new JPanel();
JPanel pane2 = new JPanel();
JLabel label = new JLabel("Please choose the restrictions:");
JLabel imgLabel1 = new JLabel(new ImageIcon(border));
JLabel notiLabel1 = new JLabel("The Pokemon chosen with these restrictions are: ");
JLabel notiLabel2 = new JLabel("'No Restrictions': No restrictions for the kind of Pokemon chosen based on species or items.");
JLabel notiLabel3 = new JLabel("'Battle Revolution': All Pokemon must have unique items.");
JLabel notiLabel4 = new JLabel("'Battle Tower': All Pokemon must have unique items, Uber and Event Legendaries banned.");
JLabel label2 = new JLabel("Please choose possible Pokemon:");
pane1.add(label);
pearlButtons();
pane1.add(R1);
pane1.add(R2);
pane1.add(R3);
pane1.add(PSubmit);
pane1.add(notiLabel2);
pane1.add(notiLabel3);
pane1.add(notiLabel4);
pane1.add(imgLabel1);
pane1.add(notiLabel1);
JLabel pokeLabel1 = new JLabel(new ImageIcon(DF));
JLabel pokeLabel2 = new JLabel(new ImageIcon(DF));
JLabel pokeLabel3 = new JLabel(new ImageIcon(DF));
JLabel pokeLabel4 = new JLabel(new ImageIcon(DF));
JLabel pokeLabel5 = new JLabel(new ImageIcon(DF));
JLabel pokeLabel6 = new JLabel(new ImageIcon(DF));
pane1.add(pokeLabel1);
pane1.add(pokeLabel2);
pane1.add(pokeLabel3);
pane1.add(pokeLabel4);
pane1.add(pokeLabel5);
pane1.add(pokeLabel6);
pane2.add(label2);
layout.add("Pearl Version", pane1);
layout.add("SoulSilver Version", pane2);
frame.add(layout);
}
public void pearlButtons()
{
PGroup = new ButtonGroup();
R1 = new JRadioButton("No Restrictions", true);
R1.setActionCommand("N");
R1.setVisible(true);
R2 = new JRadioButton("Battle Revolution");
R2.setActionCommand("BR");
R2.setVisible(true);
R3 = new JRadioButton("Battle Tower");
R3.setActionCommand("B");
R3.setVisible(true);
PGroup.add(R1);
PGroup.add(R2);
PGroup.add(R3);
PSubmit = new JButton("Submit");
PSubmit.setActionCommand("pstart");
PSubmit.setVisible(true);
PSubmit.addActionListener(this);
}
public void pearlProcessing()
{
//The "list" array has a bunch of string names that get .png affixed to them (and I named the image files as such when I name them)
String file1 = list[0] + ".png";
String file2 = list[1] + ".png";
String file3 = list[2] + ".png";
String file4 = list[3] + ".png";
String file5 = list[4] + ".png";
String file6 = list[5] + ".png";
/*-------------------------------------------------------------------------------//
This is where the method's supposed to go to change the image...
I've tried pokeLabel = new JLabel(new ImageIcon(file1));, but that yields a NullPointerException.
//-----------------------------------------------------------------------------------*/
}
public static void main(String[] args)
{
Shell test = new Shell();
test.setFrame();
test.frameLayout();
test.frame.setVisible(true);
}
public void actionPerformed(ActionEvent e)
{
if ("pstart".equals(e.getActionCommand()))
{
result = PGroup.getSelection().getActionCommand();
if (result.equals("N"))
{
list = driver.Prandom();
pearlProcessing();
}
else
System.out.println("Not done yet! ;)");
}
}
public void menuKeyPressed(MenuKeyEvent e)
{
System.out.println("pressed");
}
public void menuKeyReleased(MenuKeyEvent e)
{
System.out.println("menuKeyReleased");
}
public void menuKeyTyped(MenuKeyEvent e)
{
System.out.println("menuKeyTyped");
}
}
Without knowing if this is the cause, I would change
result = PGroup.getSelection().getActionCommand();
if (result.equals("N")) {
to
ButtonModel selection = PGroup.getSelection();
result = (selection==null ? null : selection.getActionCommand());
if ("N".equals(result)) {
// etc...
This guards against likely null pointers.
I highly suggest whenever you get any exception to always look at the stack trace and see where the actual line the exception occurred at was.
But if I were to speculate, you call PGroup.getSelection() in your actionPerformed method. This method may return null if there is no button selected in your radio button group. I also noticed that you do not set an initially selected radio button (call setSelected(true) on the radio button). Thus, if the selected radio button is null calling getActionCommand will result in a NullPointerException.