Including JCheckBox in JFrame as and when a client connects - java

I am trying to write a server application in java and creating a vector v1 to store all the sockets that hit the server.
Next i made an arraylist where i stored all my Client sockets as objects and then created a JCheckBox array where I loop it to add checkbox to the JPanel controlpanel which was initiated in the class contructor but something seems to be going wrong and i can't see any checkbox.
import java.util.*;
import java.net.*;
import javax.swing.*;
import java.awt.event.*;
import java.io.*;
import java.awt.*;
class server extends JFrame implements ActionListener {
JTextArea t1;
PrintWriter pw;
JButton b1, b2;
static Vector v1 = new Vector();
static ArrayList checks = new ArrayList();
static JPanel controlpanel;
server() {
setLayout(new FlowLayout());
t1 = new JTextArea();
add(t1);
b1 = new JButton("Send to All");
b2 = new JButton("Send");
//b1.addActionListener(this);
//b2.addActionListener(this);
add(b2, BorderLayout.SOUTH);
add(b1, BorderLayout.NORTH);
b1.addActionListener(this);
b2.addActionListener(this);
controlpanel = new JPanel();
controlpanel.setVisible(true);
add(controlpanel);
}
public void actionPerformed(ActionEvent ae) {
String m = t1.getText();
if (ae.getSource() == b1) {
try {
Iterator t2 = v1.iterator();
while (t2.hasNext()) {
Socket s = (Socket) t2.next();
pw = new PrintWriter(s.getOutputStream(), true);
pw.println(m);
pw.flush();
System.out.println("send" + m);
}
} catch (Exception e) {
}
}
if (ae.getSource() == b2) {
try {
Iterator itr = checks.iterator();
while (itr.hasNext()) {
Socket schecked = (Socket) itr.next();
pw = new PrintWriter(schecked.getOutputStream(), true);
pw.println(m);
pw.flush();
System.out.println("sent " + m);
}
} catch (Exception e) {
}
}
t1.setText("");
}
public static void main(String z[]) {
try {
new server().setVisible(true);
ServerSocket s = new ServerSocket(2000);
while (true) {
System.out.println("waiting...");
Socket c = s.accept();
// System.out.print(c);
v1.add(c);
for (int i = 0; i < v1.size(); i++) {
checks.add(v1.get(i));
// checks[i].setText()=v1[i];
}
JCheckBox checkbox[] = new JCheckBox[checks.size()];
for (int i = 0; i < checks.size(); i++) {
// Object o=checks.get(i);
checkbox[i] = new JCheckBox();
// checkbox[i].setText()=checks.get(i).name;
controlpanel.add(checkbox[i]);
checkbox[i].setSelected(true);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

As you are adding UI elements after the JFrame has been made visible, you need to call revalidate() on the panel. Also you should never add directly from a thread which is not the Event Dispatch Thread. Finally, it appears every time a new client connects, you're going to re-add all the checkbox you already have added, plus one (i.e. when the first client connects you will have 1 checkbox, when the second connects you'll have 1 + 2 = 3, when the third connects you'll have 1 + 2 + 3 = 6, etc.).
I strongly suggests you mentally run through your code, instruction by instruction, to see what happens. Alternatively, if you're using a decent IDE, you can step through the code in the debugger and inspect the content of controlPanel. If you're not using an IDE... you should.
I don't quite understand what you need check[] and v1[] for but assuming that you do need them, instead of maintaining three arrays you can define a class containing a variable for a check, one for a v1, and one for a checkbox, and maintain a single array of instances of such objects.

Related

Java Multiple Checkboxes and Executing Multiple Statements

new to programming and Java is the first language I'm learning.
I'm having difficulty thinking through the logic on this application I'm building. The application is really simple: it has say five checkboxes and a sync button. You select a checkbox and click sync and it runs a cmd command associated with the specific checkbox.
However, I would like to be able to check multiple checkboxes and hit sync and have them all go instead of doing it one at a time. I currently have an if statement (if the checkbox is selected and sync button is pressed) run "xyz" command (that corresponds to that checkbox). But it only runs for the first checkbox (if) and then quits.
Thanks!
Edit. Code below:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.IOException;
import java.util.Scanner;
class RcSync extends JFrame implements ActionListener{
Container contentPane = getContentPane();
JPanel top = new JPanel();
JPanel center = new JPanel();
JPanel bottom = new JPanel();
JScrollPane mainScrollFrame = new JScrollPane(center);
JLabel displayMessage = new JLabel("Please select a item, and click sync:");
Font customFontHeader = new Font("", Font.BOLD,15);
JButton syncButton = new JButton("Sync");
JButton cancelButton = new JButton("Cancel");
String[] database = {"Apple","Pineapple","Orange","Pear","Fig"};
JCheckBox chk1 = new JCheckBox(database[0]);
JCheckBox chk2 = new JCheckBox(database[1]);
JCheckBox chk3 = new JCheckBox(database[2]);
JCheckBox chk4 = new JCheckBox(database[3]);
JCheckBox chk5 = new JCheckBox(database[4]);
JCheckBox chk6 = new JCheckBox(database[5]);
public RcSync() {
super ("Sync Application");
setSize (400,450);
setDefaultCloseOperation(EXIT_ON_CLOSE);
add(top);
setVisible(true);
top.add(displayMessage);
displayMessage.setFont(customFontHeader);
center.add(chk1);
center.add(chk2);
center.add(chk3);
center.add(chk4);
center.add(chk5);
bottom.add(syncButton);
syncButton.addActionListener(this);
cancelButton.addActionListener(new CloseListener());
bottom.add(cancelButton);
bottom.add(emailButton);
emailButton.addActionListener(this);
contentPane.add("North", top);
contentPane.add("South", bottom);
this.getContentPane().add(mainScrollFrame, BorderLayout.CENTER);
center.setLayout(new BoxLayout(center, BoxLayout.Y_AXIS));
}
public void actionPerformed(ActionEvent event){
if ((event.getSource() == syncButton) && (chk1.isSelected())) {
try {
Runtime.getRuntime().exec("cmd /c start \"\" C:\\File\\script.bat " + chk1.getText());
} catch (IOException e) {
e.printStackTrace();}
}
if ((event.getSource() == syncButton) && (chk2.isSelected())) {
try {
Runtime.getRuntime().exec("cmd /c start \"\" C:\\File\\script.bat " + chk2.getText());
} catch (IOException e) {
e.printStackTrace();}
}
if ((event.getSource() == syncButton) && (chk3.isSelected())) {
try {
Runtime.getRuntime().exec("cmd /c start \"\" C:\\File\\script.bat " + chk3.getText());
} catch (IOException e) {
e.printStackTrace();}
}
if ((event.getSource() == syncButton) && (chk4.isSelected())) {
try {
Runtime.getRuntime().exec("cmd /c start \"\" C:\\File\\script.bat " + chk4.getText());
} catch (IOException e) {
e.printStackTrace();}
}
if ((event.getSource() == syncButton) && (chk5.isSelected())) {
try {
Runtime.getRuntime().exec("cmd /c start \"\" C:\\File\\script.bat " + chk5.getText());
} catch (IOException e) {
e.printStackTrace();}
}
}
private class CloseListener implements ActionListener{
#Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
}
public static void main (String[]args){
RsSync gui = new RcSsync();
}
}
}
I have edited my response since you provided more context to your question. Pasted below: is my approach to solving your problem, working code with explanation, and errors I had to resolve with your associated code:
Approach: Associate a boolean value for each checkbox corresponding to whether or not that option has been 'selected by the end user'. When the sync button is clicked, find which checkboxes have been selected. These checkboxes will return a true value from their isSelected() method. For each checkbox selected add the associated command into a List containing all the commands to be ran on the end user's machine. Iterate through this list until there are no commands left to be ran.
Code:
import javax.swing.*;
import java.util.ArrayList;
import java.awt.*;
import java.awt.event.*;
import java.util.List;
class RcSync extends JFrame implements ActionListener{
Container contentPane = getContentPane();
JPanel top = new JPanel();
JPanel center = new JPanel();
JPanel bottom = new JPanel();
JScrollPane mainScrollFrame = new JScrollPane(center);
JLabel displayMessage = new JLabel("Please select a item, and click sync:");
Font customFontHeader = new Font("", Font.BOLD,15);
JButton syncButton = new JButton("Sync");
JButton cancelButton = new JButton("Cancel");
// Encapsulate your checkboxes to commands, since there is one
// to one relationship and makes future changes easier since there is a single point of change
String[] database = {"Apple","Pineapple","Orange","Pear","Fig"};
CheckboxCommand chk1 = new CheckboxCommand("Checkbox 1 cmd", new JCheckBox(database[0]));
CheckboxCommand chk2 = new CheckboxCommand("Checkbox 2 cmd", new JCheckBox(database[1]));
CheckboxCommand chk3 = new CheckboxCommand("Checkbox 3 cmd", new JCheckBox(database[2]));
CheckboxCommand chk4 = new CheckboxCommand("Checkbox 4 cmd", new JCheckBox(database[3]));
CheckboxCommand chk5 = new CheckboxCommand("Checkbox 5 cmd", new JCheckBox(database[4]));
public RcSync() {
super ("Sync Application");
setSize (400,450);
setDefaultCloseOperation(EXIT_ON_CLOSE);
add(top);
setVisible(true);
top.add(displayMessage);
displayMessage.setFont(customFontHeader);
center.add(chk1.checkbox);
center.add(chk2.checkbox);
center.add(chk3.checkbox);
center.add(chk4.checkbox);
center.add(chk5.checkbox);
bottom.add(syncButton);
syncButton.addActionListener(this);
cancelButton.addActionListener(new CloseListener());
bottom.add(cancelButton);
// TODO email button doesn't exist, assuming copy/paste error?
// bottom.add(emailButton);
// emailButton.addActionListener(this);
contentPane.add("North", top);
contentPane.add("South", bottom);
this.getContentPane().add(mainScrollFrame, BorderLayout.CENTER);
center.setLayout(new BoxLayout(center, BoxLayout.Y_AXIS));
}
public void actionPerformed(ActionEvent event){
// Implements the approach I described initially
if (event.getSource() == syncButton){
List<String> cmdsToRun = new ArrayList<>();
if (chk1.isSelected()){
cmdsToRun.add(chk1.getCmdToRun());
}
if (chk2.isSelected()){
cmdsToRun.add(chk2.getCmdToRun());
}
if (chk3.isSelected()){
cmdsToRun.add(chk3.getCmdToRun());
}
if (chk4.isSelected()){
cmdsToRun.add(chk4.getCmdToRun());
}
if (chk5.isSelected()){
cmdsToRun.add(chk5.getCmdToRun());
}
// Note: for verification purposes I just print out your commands
// since they're hard coded to your particular environment
System.out.println(cmdsToRun);
// This is where you would loop through your command list i.e.
// for (int x=0; x<cmdsToRun; x++){ //run command at cmdToRun.get(x); }
}
}
private class CloseListener implements ActionListener{
#Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
}
// encapsulating your checkboxes to commands
private class CheckboxCommand {
private String cmdToRun;
private boolean isSelected;
private JCheckBox checkbox;
public CheckboxCommand(String cmdToRun, JCheckBox checkbox) {
this.cmdToRun = cmdToRun;
this.checkbox = checkbox;
}
public String getCmdToRun() {
return cmdToRun;
}
public void setCmdToRun(String cmdToRun) {
this.cmdToRun = cmdToRun;
}
public boolean isSelected() {
return this.checkbox.isSelected();
}
public void setSelected(boolean selected) {
isSelected = selected;
}
}
public static void main (String[]args){
// Fixed your typo error to run the swing interface
RcSync gui = new RcSync();
}
}
Verification of correct code:
Key Insight:
I encapsulated your commands to checkboxes into a private class since there is a one to one relationship and this will allow your code to have a single point of change, which in general is a best practice :)
Side Note:
I don't actually run your commands on my end since they're tied to your particular machine. I.e. associated to local scripts, so I printed out dummy commands to prove the code functions appropriately. I added a comment block in the code to show where you can add your environment specific code i.e. Runtime.getRuntime().exec("<CMD>");
Errors to be fixed:
I removed this line: JCheckBox chk6 = new JCheckBox(database[5]); since this will throw an indexOutOfBounds exception since there are only 5 elements in your in-memory database variable not 6.
emailButton doesn't exist so I commented it out:
// bottom.add(emailButton);
// emailButton.addActionListener(this);
This is a typo and won't run the gui: RsSync gui = new RcSsync(); so I changed it appropriately: RcSync gui = new RcSync();
Hopefully that helps! :)

Reading URL from a console and printing it in textarea in GUI

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);

how to i pass input from GUI to client than to server?

I'm very new to Java here. I have a program which acts like a calculator between client and server. the client will enter their function like this (+ 1 2). But now Im giving it a GUI interface. How do i pass the user input from GUI to client console then pass it to the server to calculate and then displaying it back to the UI? i just need something simple.
client
import java.io.*;
import java.net.Socket;
import java.util.Scanner;
import java.awt.*; // using AWT containers and components
import java.awt.event.*; // using AWT events and listener interfaces
import javax.swing.*;
public class mathClient extends JFrame implements ActionListener {
private int count = 0;
private JFrame frame;
private JPanel panel;
private JLabel lblInput;
private JLabel lblOutput;
private JTextField tfInput;
private JTextField tfOutput;
/** The entry main() method */
public static void main(String[] args) throws Exception {
// Invoke the constructor to setup the GUI, by allocating an instance
mathClient app = new mathClient();
}
public void actionPerformed(ActionEvent event){
try{
Socket clientSocket = new Socket("localhost", 50000);
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
PrintWriter print = new PrintWriter(clientSocket.getOutputStream(), true);
String input;
String output;
//String input;
while(true){
//System.out.println("Please enter your function and numbers:");
input = tfInput.getText();
print.println(input);
if(input.equals("disconnect")){
break;
}
output = inFromServer.readLine();
System.out.println(output);
tfOutput.setText(output);
}
clientSocket.close();
}
catch (Exception e)
{
}
}
public mathClient()
{
Container contentPane = getContentPane();
contentPane.setLayout(new BorderLayout());
JFrame frame = new JFrame("Calculator");
JPanel panel = new JPanel();
JLabel lblInput = new JLabel("Input: ");
JLabel lblOutput = new JLabel("Output: ");
JTextField tfInput = new JTextField();
tfInput.setEditable(true);
// tfInput.addActionListener();
JTextField tfOutput = new JTextField();
tfOutput.setEditable(false);
JButton btnCalculate = new JButton("Calculate");
btnCalculate.addActionListener(this);
frame.add(panel);
panel.add(lblInput);
panel.add(tfInput);
panel.add(lblOutput);
panel.add(tfOutput);
panel.add(btnCalculate);
tfInput.setPreferredSize(new Dimension(200, 30));
tfOutput.setPreferredSize(new Dimension(200, 30));
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(230,250);
frame.setResizable(false);
frame.setVisible(true);
}
}
Server
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
// Takes in a mathematical operation and the operands from a client and returns the result
// Valid operations are add, sub, multiply, power, divide, remainder, square
public class mathServer
{
public static void main(String [] args) throws IOException
{
ServerSocket welcomeSocket = new ServerSocket(50000); //put server online
while(true)
{
System.out.println("Waiting for connection...");
Socket connectionSocket = welcomeSocket.accept(); //open server to connections
System.out.println("Connection accepted");
process(connectionSocket); //process accepted connection
System.out.println("Connection closed");
}
}
//BufferedReader(Reader r)
static void process(Socket welcomeSocket) throws IOException
{
InputStream in = welcomeSocket.getInputStream();
BufferedReader buffer = new BufferedReader(new InputStreamReader(in));
OutputStream out = welcomeSocket.getOutputStream();
PrintWriter print = new PrintWriter(out, true);
String input = buffer.readLine(); //get user input from client
while(input != null && !input.equals("disconnect")) //check for input, if bye exit connection
{
int answer = operate(input); //perform desired operation on user input
print.println(answer); //print out result
input = buffer.readLine(); //get next line of input
}
welcomeSocket.close();
}
//Talk to the client
static int operate(String s)
{
System.out.println(s); //check if same as client input
Scanner scanner = new Scanner(s);
char option = scanner.next().charAt(0); //gets desired operation
System.out.println(option); //checks for correct operation
switch (option) {
case '+':
return (scanner.nextInt() + scanner.nextInt());
case '-':
return (scanner.nextInt() - scanner.nextInt());
case '*':
return (scanner.nextInt() * scanner.nextInt());
case '^':
return (int) Math.pow(scanner.nextInt(), scanner.nextInt());
case '/':
return scanner.nextInt() / scanner.nextInt();
case '%':
return scanner.nextInt() % scanner.nextInt();
case 's':
return (int) Math.pow(scanner.nextInt(), 2);
default:
return (int) Math.pow(scanner.nextInt(), 3);
}
}
}
One of the problems is an NullPointerException in actionPerformed(). However it is not visible as you have an empty catch block. You should never have empty catch blocks. Change it to:
catch (Exception e) {
e.printStackTrace();
}
The members tfInput and tfOutput are null in actionPerformed() as they are never initialized. The constructor mathClient() allocates local variables JTextField tfInput and JTextField tfInput and overshadows the relevant members.
Other than the endless while loop there are several other immediate problems. You should not block Swing's Event Dispatch Thread with a socket. Consider using an auxiliary thread or a SwingWorker.
See Concurrency in Swing for details and examples.

Array of ImageIcons, change contents of array on drag and drop

I have an array of ImageIcons, and I can drag and drop other Icons onto them to replace them. When I hit a button a new JFrame is created from the array of ImageIcons.
If I do this without dragging any other Icons on to the original array, it works. However once I drop a different imageicon into the array, I get an error when I hit the button.
I'm just wondering if this is even possible at all?
I've considered other approaches of using a JTable for the top panel, or trying to use an ArrayList, but I'm not too comfortable using them. If anyone has any opinion on how this should be done, please let me know!
I shortened this example as much as possible(at 200 lines it's not exactly short). But this is exactly what my problem is...
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Properties;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import java.io.*;
import java.lang.String.*;
public class test extends JFrame {
JPanel storyPanel, rightStoryPanel, leftStoryPanel,centerStoryPanel, imageSelectPanel, CreatePanel, storyFramePanel, storycard;
TransferHandler handler;
MouseListener listener;
CardLayout cl3;
JLabel[] storyLabel = new JLabel[20];
JButton playStory, nextStory,addtargetbutton;
int count, start, i, j,stop, start1;
public test(){
CreatePanel = new JPanel(new BorderLayout());
storyPanel = new JPanel(new BorderLayout());
rightStoryPanel = new JPanel(new GridLayout(6,1));
leftStoryPanel = new JPanel(new GridLayout(6,1));
centerStoryPanel = new JPanel();
JScrollPane centerscroll = new JScrollPane(centerStoryPanel);
addtargetbutton = new JButton("Add Another Image Slot");
addtargetbutton.addActionListener(new createbuttons());
playStory = new JButton("Play your story!");
leftStoryPanel.add(playStory);
playStory.addActionListener(new createbuttons());
leftStoryPanel.add(addtargetbutton);
imageSelectPanel = new JPanel(new FlowLayout());
storyPanel.add(rightStoryPanel,BorderLayout.EAST);
storyPanel.add(leftStoryPanel, BorderLayout.WEST);
storyPanel.add(centerscroll, BorderLayout.CENTER);
CreatePanel.add(storyPanel, BorderLayout.NORTH);
CreatePanel.add(imageSelectPanel, BorderLayout.CENTER);
count= 3;
start= 0;
stop = 0;
start1= 0;
ImageSelection();
targetpanel();
getContentPane().add(CreatePanel);
}//End Create}
public void ImageSelection(){
int i = 0;
int j = 0;
TransferHandler handler = new TransferHandler("icon") {
#Override
public boolean canImport(TransferSupport support) {
return super.canImport(support)
&& support.getComponent().getParent() != imageSelectPanel;}
};
MouseListener listener = new MouseAdapter(){
public void mousePressed(MouseEvent e){
JComponent c = (JComponent) e.getSource();
TransferHandler handler = c.getTransferHandler();
handler.exportAsDrag(c, e, TransferHandler.COPY);
System.out.println(e);}
}; // Drag & Drop mouse
try{
String imagePath = "";
BufferedImage[] CreateImagesFromDB = new BufferedImage[40];
JLabel[] ImageLabel = new JLabel[40];
while (count > start1) {
i = 1;
CreateImagesFromDB[i] = ImageIO.read(new File("one.jpg"));
ImageLabel[i] = new JLabel(new ImageIcon(CreateImagesFromDB[i]));
imageSelectPanel.add(ImageLabel[i]);
ImageLabel[i].addMouseListener(listener);
ImageLabel[i].setTransferHandler(handler);
i++;
start1++;
}
}//EndTRY
catch(Exception e){
System.out.println("CATCH"+ e);
}//end catch
}
public void targetpanel(){
TransferHandler handler = new TransferHandler("icon") {
#Override
public boolean canImport(TransferSupport support) {
return super.canImport(support)
&& support.getComponent().getParent() != imageSelectPanel;
}
};
MouseListener listener = new MouseAdapter(){
public void mousePressed(MouseEvent e){
JComponent c = (JComponent) e.getSource();
TransferHandler handler = c.getTransferHandler();
handler.exportAsDrag(c, e, TransferHandler.COPY);
}
};
BufferedImage[] storyImages = new BufferedImage[20];
try{
while(count > start){
storyImages[j] = ImageIO.read(new File("TargetImg.jpg"));
storyLabel[j] = new JLabel(new ImageIcon(storyImages[j]));
centerStoryPanel.add(storyLabel[j]);
storyLabel[j].addMouseListener(listener);
storyLabel[j].setTransferHandler(handler);
j++;
start++;
centerStoryPanel.revalidate();
//validate();
System.out.println("J in Loop is: "+j );
}//end while Loop
//System.out.println("J is equalto: "+j);
} catch(Exception e) {};
}// End TargetPanel
public void storyFrame (JLabel[] storyArray){
int i = 0;
storyFramePanel = new JPanel(new BorderLayout());
nextStory = new JButton("Next Image");
nextStory.addActionListener(new createbuttons());
storycard = new JPanel();
cl3 = new CardLayout();
storycard.setLayout(cl3);
JPanel[] storyImgPanel = new JPanel[20];
JLabel[] imglab = new JLabel[20];
storyImgPanel[i]= new JPanel();
while( i < j){
storyImgPanel[i].add(new JLabel(storyArray[i].getIcon()));
storycard.add(storyImgPanel[i], ""+i);
i++;
}
JFrame story = new JFrame("Story");
story.setSize(500,500);
storyFramePanel.add(storycard, BorderLayout.CENTER);
storyFramePanel.add(nextStory, BorderLayout.EAST);
story.add(storyFramePanel);
cl3.show(storycard, "1");
story.setVisible(true);
}
public static void main(String[] args){
System.out.println("Application Running");
JFrame mainframe = new test();
mainframe.setTitle("Let Me Know!");
mainframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainframe.setSize(1000,1000);
mainframe.setVisible(true);
}
class createbuttons implements ActionListener{
public void actionPerformed(ActionEvent e)
{
if(e.getSource() == addtargetbutton){
count++;
targetpanel();
System.out.println("Trying to add another TargetImg, count = "+count);
}
if(e.getSource() == playStory){
storyFrame(storyLabel);
}
if(e.getSource() == nextStory){
cl3.next(storycard);
System.out.println("button pressed");
}
}
}
}
I figured it out:
Firstly, each time you call targetpanel(), you create a new instance of storyLabel, but then you are behaving like you have it already populated from the previous calls. So the result is:
first call:
storyLabel[0] = something;
storyLabel[1] = something;
storyLabel[2] = something;
storyLabel[3] = null;
storyLabel[4] = null.... etc
second call (you added another image slot):
storyLabel[0] = null;
storyLabel[1] = null;
storyLabel[2] = null;
storyLabel[3] = something;
storyLabel[4] = null.... etc
So when you use this array in the storyboard, you get NullPointerException.
You need to create the array only once. So remove storyLabel = new JLabel[20] from targetpanel() and initialize the array in the constructor, or even better in the declaration:
...
CardLayout cl3;
JLabel[] storyLabel = new JLabel[20];
JButton playStory, nextStory, addtargetbutton;
...
Secondly, when displaying the images using the storyFrame(), you change the parent of the supplied JLabels and they subsequently disappear from the storyPanel. You must create new instances of JLabel for the storyboard.
In storyFrame(), instead of
storyImgPanel[i].add(storyArray[i]);
write
storyImgPanel[i].add(new JLabel(storyArray[i].getIcon()));
If I do all this the program is working.
There's not enough in your code to really give you a good answer. One of these two lines:
storyImgPanel[i].add(storyArray[i]);
storycard.add(storyImgPanel[i], ""+i);
would be my guess. The component you're adding in is null (either storyArray[i] or storyImgPanel[i]. Probably the first, since you're creating the second in the loop.
If you could post all your code, it would be easier. Or, (preferably) post a self-contained small example.

proper way to listen to key presses java

What is the best way to handle key presses in Java? I was trying to set up my KeyListener code but then I saw online KeyBinding is what should be used but after reading
http://download.oracle.com/javase/tutorial/uiswing/misc/keybinding.html
and not being able to find any tutorials online I am even more confused.
Here is what i have been trying:
frame = new JFrame("Jay's Game Title");
Container panel = (JPanel)frame.getContentPane();
...
panel.setFocusable(true);
panel.requestFocus();
panel.addKeyListener(this);//TODO:fix me please, this is not working
frame.setSize(1024, 768);
frame.setVisible(true);
frame.setFocusable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
but to no avail. Any help is much appreciated and in the meantime I will continue to look over others' posts and pull more of my hair out.
note: my code for my buttons work just great, and I would love to have my keypresses handled in another keypresses.java file or something to keep it organized
package com.jayavon.game.client;
/****************************************************************
* Author : ***REMOVED***
* Start Date : 09/04/2011
* Last Update : 10/04/2011
*
* Description
* This is the video game application
* This application is used to sending and receiving the messages
* and all of the game data(soon, hopefully :p).
*
* Remarks
* Before running the client application make sure the server is
* running.
******************************************************************/
import javax.swing.*;
import java.awt.Container;
import java.awt.event.*;
import java.io.*;
import java.net.*;
import java.util.ArrayList;
import java.util.Iterator;
public class MyClient extends JFrame implements ActionListener, KeyListener{
JFrame frame;
JTextField chatBoxTxt;
JButton sendButton, exitButton, onlineButton, backpackButton, characterButton, helpButton, optionsButton, questsButton, skillsButton;
JInternalFrame skillsFrame, onlineFrame;
DefaultListModel modelChatList;
JList listForChat;
JScrollPane chatScrollPane;
DefaultListModel modelUserList;
JList listForUsers;
JScrollPane userListScrollPane;
String name, password;
Socket s, s1, s2;
DataInputStream messageIn;
DataOutputStream messageOut;
DataInputStream userNameIn;
DataOutputStream userNameOut;
DataOutputStream userLogOut;
MyClient(String name, String password) throws IOException{
this.name = name;
initGUI();
s = new Socket("localhost",1004); //creates a socket object
s1 = new Socket("localhost",1004);
s2 = new Socket("localhost",1004);
//create input-stream for a particular socket
messageIn = new DataInputStream(s.getInputStream());
//create output-stream
messageOut = new DataOutputStream(s.getOutputStream());
//sending a message for login
messageOut.writeUTF(name + " has joined the game.");
userLogOut = new DataOutputStream(s1.getOutputStream());
userNameOut = new DataOutputStream(s2.getOutputStream());
userNameIn = new DataInputStream(s2.getInputStream());
//creating a thread for maintaining the list of user name
MyUserNameReciever userNameReciever = new MyUserNameReciever(userNameOut, modelUserList, name, userNameIn);
Thread userNameRecieverThread = new Thread(userNameReciever);
userNameRecieverThread.start();
//creating a thread for receiving a messages
MyMessageReciever messageReciever = new MyMessageReciever(messageIn, modelChatList);
Thread messageRecieverThread = new Thread(messageReciever);
messageRecieverThread.start();
}
public void initGUI(){
frame = new JFrame("Jay's Game Title");
Container panel = (JPanel)frame.getContentPane();
chatBoxTxt = new JTextField();
panel.add(chatBoxTxt);
chatBoxTxt.setBounds(5,605,650,30);
chatBoxTxt.setVisible(false);
sendButton = new JButton("Send");
sendButton.addActionListener(this);
panel.add(sendButton);
sendButton.setBounds(260,180,90,30);
modelChatList = new DefaultListModel();
listForChat = new JList(modelChatList);
chatScrollPane = new JScrollPane(listForChat);
panel.add(chatScrollPane);
chatScrollPane.setBounds(5,640,650,80);
modelUserList = new DefaultListModel();
listForUsers = new JList(modelUserList);
userListScrollPane = new JScrollPane(listForUsers);
userListScrollPane.setSize(100,250);
userListScrollPane.setVisible(false);
backpackButton = new JButton(new ImageIcon("images/gui/button_backpack.png"));
backpackButton.addActionListener(this);
backpackButton.setBounds(660,686,33,33);
backpackButton.setBorderPainted(false);backpackButton.setFocusPainted(false);
backpackButton.setToolTipText("Backpack[B]");
panel.add(backpackButton);
characterButton = new JButton(new ImageIcon("images/gui/button_character.png"));
characterButton.addActionListener(this);
characterButton.setBounds(695,686,33,33);
characterButton.setBorderPainted(false);characterButton.setFocusPainted(false);
characterButton.setToolTipText("Character[C]");
panel.add(characterButton);
skillsButton = new JButton(new ImageIcon("images/gui/button_skills.png"));
skillsButton.addActionListener(this);
skillsButton.setBounds(730,686,33,33);
skillsButton.setBorderPainted(false);skillsButton.setFocusPainted(false);
skillsButton.setToolTipText("Skills[V]");
panel.add(skillsButton);
questsButton = new JButton(new ImageIcon("images/gui/button_quests.png"));
questsButton.addActionListener(this);
questsButton.setBounds(765,686,33,33);
questsButton.setBorderPainted(false);questsButton.setFocusPainted(false);
questsButton.setToolTipText("Quests[N]");
panel.add(questsButton);
onlineButton = new JButton(new ImageIcon("images/gui/button_online.png"));
onlineButton.addActionListener(this);
onlineButton.setBounds(800,686,33,33);
onlineButton.setBorderPainted(false);onlineButton.setFocusPainted(false);
onlineButton.setToolTipText("Online List[U]");
panel.add(onlineButton);
helpButton = new JButton(new ImageIcon("images/gui/button_help.png"));
helpButton.addActionListener(this);
helpButton.setBounds(835,686,33,33);
helpButton.setBorderPainted(false);helpButton.setFocusPainted(false);
helpButton.setToolTipText("Help[I]");
panel.add(helpButton);
optionsButton = new JButton(new ImageIcon("images/gui/button_options.png"));
optionsButton.addActionListener(this);
optionsButton.setBounds(870,686,33,33);
optionsButton.setBorderPainted(false);optionsButton.setFocusPainted(false);
optionsButton.setToolTipText("Options[O]");
panel.add(optionsButton);
exitButton = new JButton(new ImageIcon("images/gui/button_exit.png"));
exitButton.addActionListener(this);
exitButton.setBounds(905,686,33,33);
exitButton.setBorderPainted(false);exitButton.setFocusPainted(false);
exitButton.setToolTipText("Exit[none]");
panel.add(exitButton);
skillsFrame = new JInternalFrame("Skills", true, true, false, false);
skillsFrame.setBounds(600, 10, 400, 500);
skillsFrame.setVisible(false);
panel.add(skillsFrame);
onlineFrame = new JInternalFrame("Users", true, true, false, false);
onlineFrame.setContentPane(userListScrollPane);
onlineFrame.setBounds(850, 10, 150, 300);
onlineFrame.setVisible(false);
panel.add(onlineFrame);
panel.setLayout(null);
panel.setFocusable(true);
panel.requestFocus();
panel.addKeyListener(this);//TODO:fix me please, this is not working
frame.setSize(1024, 768);
frame.setVisible(true);
frame.setFocusable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void actionPerformed(ActionEvent e){
// sending the messages
if(e.getSource() == sendButton && chatBoxTxt.isVisible() == false){
chatBoxTxt.setVisible(true);
chatBoxTxt.requestFocus(true);
} else if (e.getSource() == sendButton && chatBoxTxt.isVisible() == true){
String str = "";
str = chatBoxTxt.getText();
if (str != ""){
str = name + ": > " + str;
try{
messageOut.writeUTF(str);
System.out.println(str);
messageOut.flush();
}catch(IOException ae)
{System.out.println(ae);}
}
//and hide chatBoxTxt
chatBoxTxt.setText("");
chatBoxTxt.setVisible(false);
}
// show user list
if (e.getSource() == onlineButton){
if (userListScrollPane.isVisible()){
userListScrollPane.setVisible(false);
} else {
userListScrollPane.setVisible(true);
}
if (onlineFrame.isVisible()){
onlineFrame.setVisible(false);
} else {
onlineFrame.setVisible(true);
}
}
// show skill list
if (e.getSource() == skillsButton){
if (skillsFrame.isVisible()){
skillsFrame.setVisible(false);
} else {
skillsFrame.setVisible(true);
}
}
// client logout
if (e.getSource() == exitButton){
int exit = JOptionPane.showConfirmDialog(this, "Are you sure you want to exit?");
if (exit == JOptionPane.YES_OPTION){
frame.dispose();
try{
//sending the message for logout
messageOut.writeUTF(name + " has logged out.");
userLogOut.writeUTF(name);
userLogOut.flush();
Thread.currentThread().sleep(1000);
System.exit(1);
}catch(Exception oe){}
}
}
}
public void windowClosing(WindowEvent w){
try{
userLogOut.writeUTF(name + " has logged out.");
userLogOut.flush();
Thread.currentThread().sleep(1000);
System.exit(1);
}catch(Exception oe){}
}
#Override
public void keyPressed(KeyEvent e) {
int id = e.getID();
//open up chatBoxTxt for typing
if (id == KeyEvent.VK_ENTER && !chatBoxTxt.isVisible()){
chatBoxTxt.setVisible(true);
chatBoxTxt.requestFocus(true);
} //it is open so want to send text
else if (id == KeyEvent.VK_ENTER && chatBoxTxt.isVisible()) {
//send message
String str = "";
str = chatBoxTxt.getText();
//make sure there is a message
if (str.length() > 0){
chatBoxTxt.setText("");
str = name + ": > " + str;
try{
messageOut.writeUTF(str);
System.out.println(str);
messageOut.flush();
}catch(IOException ae)
{System.out.println(ae);}
}
//and hide chatBoxTxt
chatBoxTxt.setVisible(false);
} //press (Map) key without chatBoxTxt being open
else if (id == KeyEvent.VK_M && !chatBoxTxt.isVisible()){
} //press (Character) key without chatBoxTxt being open
else if (id == KeyEvent.VK_C && !chatBoxTxt.isVisible()){
} //press (Backpack) key without chatBoxTxt being open
else if (id == KeyEvent.VK_B && !chatBoxTxt.isVisible()){
}
}
#Override
public void keyReleased(KeyEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void keyTyped(KeyEvent arg0) {
// TODO Auto-generated method stub
}
// class is used to maintain the list of user name
class MyUserNameReciever implements Runnable{
DataOutputStream userNameOut;
DefaultListModel modelUserList;
DataInputStream userNameIn;
String name, lname;
ArrayList alname = new ArrayList(); //stores the list of user names
ObjectInputStream obj; // read the list of user names
int i = 0;
MyUserNameReciever(DataOutputStream userNameOut, DefaultListModel modelUserList, String name, DataInputStream userNameIn){
this.userNameOut = userNameOut;
this.modelUserList = modelUserList;
this.name = name;
this.userNameIn = userNameIn;
}
public void run(){
try{
userNameOut.writeUTF(name); // write the user name in output stream
while(true){
obj = new ObjectInputStream(userNameIn);
//read the list of user names
alname = (ArrayList)obj.readObject();
if(i>0)
modelUserList.clear();
Iterator i1 = alname.iterator();
System.out.println(alname);
while(i1.hasNext()){
lname = (String)i1.next();
i++;
//add the user names in list box
modelUserList.addElement(lname);
}
}
}catch(Exception oe){}
}
}
//class is used to received the messages
class MyMessageReciever implements Runnable{
DataInputStream messageIn;
DefaultListModel modelChatList;
MyMessageReciever(DataInputStream messageIn, DefaultListModel modelChatList){
this.messageIn = messageIn;
this.modelChatList = modelChatList;
}
public void run(){
String incommingMessage = "";
while(true){
try{
incommingMessage = messageIn.readUTF(); // receive the message from server
// add the message in list box
modelChatList.addElement(incommingMessage);
/* forces chat to bottom of screen :TODO but doesn't allow scrolling up
chatScrollPane.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() {
public void adjustmentValueChanged(AdjustmentEvent e) {
e.getAdjustable().setValue(e.getAdjustable().getMaximum());
}});*/
}catch(Exception e){}
}
}
}
}
and not being able to find any tutorials online I am even more confused.
That link is a tutorial. Unless you ask a specific question we don't know what you don't understand.
my code for my buttons work just great
It looks like you want the Enter key to do the same processing as clicking on a button. In this case the simple solution is to add an ActionListener to the text field instead of using Key Bindings. You should NOT even consider using a KeyListener for this.
Of course this means you need to redesign your program to use a different ActionListener for each button. So you need "Send", "Online", "Skills", and "Exit" ActionListeners. Then the "Send" ActionListener can be used by both the send button and the text field.
Edit:
for example: the user can hit (VK_V) or click the skills button to show the skills internal frame
You would use Key Bindings for this. You can do the bindings manually as described in the tutorial.
Or, an easier solution is to use a JMenu with menu items to invoke your Actions. Then you can just set an Accelerator for the menu item. Read the section from the Swing tutorial on How to Use Menus for more information.
Any further help will require you to post your SSCCE,

Categories