Ive been following TheCherno's network chat programming tutorials, and I am almost done, just fixing bugs when I ran into a problem. I have a button that opens a window that is supposed to have a list of all the connected users listed. However, everytime I test it, the only item on the list is the first person who connected to that instance of the server. It is the same for all of the other users connected as well. I have no errors in my code, and it all seems correct. I can't seem to find the error.
This function is called from a while running loop, and everything else in it is working constantly, so I don't think there is something wrong in this.
private void sendStatus() {
if (clients.size() <= 0) return;
String users = "/u/";
for (int i = 0; i < clients.size() - 1; i++) {
users += clients.get(i).name + "/n/";
}
users += clients.get(clients.size() - 1).name + "/e/";
sendToAll(users);
}
This is from another class, where the client decodes the messages sent from the server.
else if (message.startsWith("/u/")) {
String[] u = message.split("/u/|/n/|/e/");
users.update(Arrays.copyOfRange(u, 1, u.length - 1));
}
And then this is the peice that handles the graphics of it, I don't see anything wrong in it, but I will include it anyway jsut in case. Thanks all!
private JPanel contentPane;
private JList list;
public OnlineUsers() {
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
setSize(200, 320);
setLocationRelativeTo(null);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
GridBagLayout gbl_contentPane = new GridBagLayout();
gbl_contentPane.columnWidths = new int[]{0, 0};
gbl_contentPane.rowHeights = new int[]{0, 0};
gbl_contentPane.columnWeights = new double[]{1.0, Double.MIN_VALUE};
gbl_contentPane.rowWeights = new double[]{1.0, Double.MIN_VALUE};
contentPane.setLayout(gbl_contentPane);
list = new JList();
GridBagConstraints gbc_list = new GridBagConstraints();
gbc_list.fill = GridBagConstraints.BOTH;
gbc_list.gridx = 0;
gbc_list.gridy = 0;
JScrollPane p = new JScrollPane();
p.setViewportView(list);
contentPane.add(p, gbc_list);
list.setFont(new Font("Verdana", 0, 14));
}
public void update(String[] users) {
list.setListData(users);
}
Still no ideas at all. I even checked the source code that the tutorial person made and its the same thing. I would really appreciate the help, as I am 14 and just learning java. Bump.
https://github.com/TheCherno/ChernoChat
Related
I am creating a messaging program that has multiple chats. On the side of the chat window there is a JPanel containing a List Array of all the buttons to switch chats.I am having trouble getting all the buttons in the side panel to be the same width, no matter what they contain. But whatever I try doesn't seem to work and I am looking for some help. Please can you explain what the code does and how it can be used so I can learn it for next time. Sorry if the comments aren't the best it's a work in progress as I wait till code works before adding detailed comments otherwise I am constantly changing them. :(
This is what it looks like without any chats:
This is with multiple chats and you can see the width variation
Here is the code that is run when a new user is added:
public void newUser() {
JPanel dialogue = new JPanel();
dialogue.setLayout(new BoxLayout(dialogue, BoxLayout.Y_AXIS));
//Creating/adding dialogue components
JLabel Enter_ip = new JLabel("Enter the ip address");
JTextField Get_ip = new JTextField("");
dialogue.add(Enter_ip);
dialogue.add(Get_ip);
dialogue.add(Box.createHorizontalStrut(15));
JLabel Enter_name = new JLabel("Enter the user's name");
JTextField Get_name = new JTextField("");
dialogue.add(Enter_name);
dialogue.add(Get_name);
//Creating the dialogue box
JOptionPane.showConfirmDialog(null, dialogue, "New User", JOptionPane.OK_CANCEL_OPTION);
//Getting data from dialogue box
String ip = Get_ip.getText();
String name = Get_name.getText();
//Try connecting to other user here
//Adding user message data
int size = Users_Messages_Data.size();
Users_Messages_Data.add(new ArrayList());//New user
Users_Messages_Data.get(size).add(new ArrayList());//Messages
Users_Messages_Data.get(size).add(new ArrayList());//Details
Users_Messages_Data.get(size).get(1).add(name);
Users_Messages_Data.get(size).get(1).add(ip);
Users_Messages_Data.get(size).get(1).add("port number");
//adds new UserButton
int temp = users.size();
users.add(new JButton(Users_Messages_Data.get(size).get(1).get(0)));
users.get(temp).addActionListener(this);
users.get(temp).setSize(new Dimension(500, 500));
SelectUser.add(users.get(temp), gbc);
Messaging.revalidate();
pack();
}
and here is the initialisation method:
public void MessagingGUI() {
//Creates JFrame and pane
Messaging = new JFrame();
Container pane = getContentPane();
JLabel info = new JLabel("29/07/2016 15:36");
//Creates user chats panel
SelectUser = new JPanel(new GridBagLayout());
gbc = new GridBagConstraints();
gbc.weightx = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridwidth = GridBagConstraints.REMAINDER;
SelectUser.setLayout(new BoxLayout(SelectUser, BoxLayout.Y_AXIS));
SelectUser.setSize(new Dimension(500, 500));
//Adds different chats
users = new ArrayList<JButton>();
int x;
for (x = 0; x < Users_Messages_Data.size(); x++) {
users.add(new JButton(Users_Messages_Data.get(x).get(1).get(0)));
users.get(x).addActionListener(this);
SelectUser.add(users.get(x), gbc);
}
JButton newUser = new JButton("+");
newUser.addActionListener(this);
SelectUser.add(newUser);
JScrollPane UserScroll = new JScrollPane(SelectUser,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
//Creates messages feed
JPanel Messages = new JPanel();
Messages.setLayout(new BoxLayout(Messages, BoxLayout.Y_AXIS));
AllMessages = new JTextArea(10, 30);
AllMessages.setBackground(Color.WHITE);
AllMessages.setEditable(false);
AllMessages.setBorder(BorderFactory.createLineBorder(Color.BLUE, 1));
JScrollPane MessageScroll = new JScrollPane(AllMessages,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
//Creates user text entry box
UserText = new JTextArea(5, 30);
//UserText.setLineWrap(true);
//UserText.setWrapStyleWord(true);
UserText.setBorder(BorderFactory.createLineBorder(Color.CYAN, 1));
UserText.setText("Enter Message. Press enter to send");
UserText.setFocusable(true);
UserText.addKeyListener(this);
UserText.setPreferredSize(new Dimension(5, 20));
//Adds all components to pane
Messages.add(info);
Messages.add(MessageScroll);
Messages.add(UserText);
pane.add(UserScroll, BorderLayout.WEST);
pane.add(Messages, BorderLayout.CENTER);
//JFrame setup
Messaging.setTitle("Messaging");
Messaging.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Messaging.setContentPane(pane);
Messaging.setVisible(true);
Messaging.setSize(400, 350);
Load_User(current_user);
}
First of all, variable names should NOT start with an upper case character. Some of your variable names are correct, other are not. Be consistent and follow Java conventions!!!
.I am having trouble getting all the buttons in the side panel to be the same width,
Don't use a BoxLayout. It does not automatically resize on the opposite axis of the layout.
Instead you can use:
a GridLayout to make all the buttons the same size. The GridLayout will also fill the area vertically which is not what you want so you will need to nest panels. So create a parent panel using a BorderLayout. Add your panel using the GridLayout with the buttons to the BorderLayout.PAGE_START of this parent panel. Then add the BorderLayout panel to the scroll pane.
a GridBagLayout. You will need to use the "fill" contstraint to have the component fill the width of the cell.
Read the Swing tutorial on Layout Managers for more information and examples.
Or maybe a different approach is to use a JList to display the users.
Tried to put on frame some swing components.
This code worked to days ago. Now it's not work, didn't nothing.
Maybe somebody can tell me what it's wrong?
public static void main(String[] args) {
JFrame mainFrame = new JFrame();
mainFrame.setSize(500, 400); //Size of frame
mainFrame.setTitle("Cinema City"); //Set title
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel mainLabel = new JLabel("Welcome to Cinema City catalog!");
JLabel actorLabel = new JLabel("Actors: ");
JLabel laLabel = new JLabel("Last added: ");
JLabel searchLabel = new JLabel("How to search ?");
GridBagConstraints gbc = new GridBagConstraints();
mainFrame.add(mainLabel, new GridBagConstraints(4, 0, 1, 3, 1, 1,
GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL,
new Insets(20, 160, 0, 0), 0, 0));
mainFrame.add(actorLabel, new GridBagConstraints(0, 0, 1, 1, 1, 1,
GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL,
new Insets(100, 0, 0, 0), 0, 0));
mainFrame.setVisible(true);
This is the error:
Exception in thread "main" java.lang.IllegalArgumentException: cannot add to layout: constraint must be a string (or null)
at java.awt.BorderLayout.addLayoutComponent(Unknown Source)
at javax.swing.JRootPane$1.addLayoutComponent(Unknown Source)
at java.awt.Container.addImpl(Unknown Source)
at java.awt.Container.add(Unknown Source)
at javax.swing.JFrame.addImpl(Unknown Source)
at java.awt.Container.add(Unknown Source)
at GUI.main(GUI.java:40)
You're not actually setting your layout to GridBagLayout, so it is still the default (which would be a FlowLayout).
Of course, only a GridBagLayout can actually handle GridBagConstraints.
This can be fixed by changing your declaration to JFrame mainFrame = new JFrame(new GridBagLayout());
Layout is not mentioned for the particular JFrame - mainframe
Add this line after the JFrame declaration
mainFrame.setLayout(new GridBagLayout());
Should work fine.
you are not set frame layout .
after creation object of frame write this code.
new GridBagLayout();
mainFrame.setLayout(gbl);
its work
i've been charged with a new software tool, and i m trying to test it.
PROBLEM:
I noticed a difference between mine GUI and the GUI of the tool run on the server:
a component is missing!
It is like if it's not shown, because i went in debug mode, and everything seems to be fine.
this image shows the different:
as you can see, the "Shaft end Dia" component is missing between the others 2 components.
CODE:
here is a code part. There are lots of items that get instantiate and added in the same way, but it doesn't apper on my pc (but they works well in others!!)
//PanelContainerClass
public class myInputPanel extends JPanel {
//myInputPanel fields
private JPanel myPanelMissing = null;
private JLabel jLabel_ofPanelMissing = null;
//myInputPanel is added to the mainFrame.
public myInputPanel() {
super();
initialize();
}
private void initialize() {
//a GridBagConstraints is created for each panel i m going to add to myInputPanel
GridBagConstraints gbc6 = new GridBagConstraints();
gbc6.gridx = 6;
gbc6.ipadx = 46;
gbc6.fill = GridBagConstraints.BOTH;
gbc6.insets = new Insets(0, 0, 0, 0);
gbc6.ipady = 0;
gbc6.gridy = 1;
//in a similiar way others gbc are instantiate
//a layout is given to myInputPanel
GridBagLayout gridBagLayout = new GridBagLayout();
gridBagLayout.columnWidths = new int[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 176, 0, 63, 0, 0, 0, 0, 0, 0, 0};
this.setLayout(gridBagLayout);
this.setSize(1185, 120);
this.setPreferredSize(new Dimension(1164, 143));
this.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED));
// add others panels to myInputPanel using this.add(getPanel_X(), gridBagConstraintsN);
this.add(getmyPanelMissing(), gridBagConstraints6);
// add others panels to myInputPanel using this.add(getPanel_Y(), gridBagConstraintsM);
}
private JPanel getmyPanelMissing() {
if (myPanelMissing == null) {
//in debug it get inside the if
jLabel_ofPanelMissing = new JLabel();
jLabel_ofPanelMissing.setHorizontalAlignment(SwingConstants.CENTER);
jLabel_ofPanelMissing.setText("<html><body>" +
"<table cellspacing='0';cellpadding='0';> <tr> <td align='center'>Shaft end Dia</td> </tr> <tr> <td align='center'>[mm]</td> </tr></table>" +
"</body></html>");
GridLayout lay = new GridLayout();
lay.setRows(1);
myPanelMissing = new JPanel();
myPanelMissing.setBorder(new SoftBevelBorder(SoftBevelBorder.RAISED));
myPanelMissing.setLayout(lay);
myPanelMissing.add(jLabel_ofPanelMissing, null);
}
return myPanelMissing;
}
}
What i tried to do is:
running it via my Eclipse: FAIL
running the jar via .bat file: FAIL
(FAIL means it doesn't appear)
running the jar on the server via .bat file: WORKS
running the jar via eclipse on a colleague's computer by downloading the code via cvs: WORKS
running the jar via .bat on colleague's computer giving him my files: WORKS
running the jar via .bat on colleague's computer with files compiled by himself: WORKS
commenting the previous panelColumn on my code: WORKS!!!!
NOTE:
1) java version: 1.7.0.75 (either on mine pc either on my collegue pc)
2) OS: window 7 on Vbox (either me and collegue)
3) Eclipse Luna 4.x (same version again for both)
QUESTION:
Has anyone had this kind of problems?
Any idea about how to solve it?
Thank you all in advance!
You must increase the area of the your panel myInputPanel with the method setBounds()
I use a Gridlayout to place 4 elements in one Line. First I had a JPanel and everything worked fine. For the case that the number of lines get to big and I have to be able to scroll down, I changed it a bit. Now I have my JPanel with one JScrollPane added on it. I used the same code, now I just add the elements to the viewport of the Jscrollpane, but now I get this exception Get java.lang.ClassCastException: layout of JScrollPane must be a ScrollPaneLayout: at javax.swing.JScrollPane.setLayout(Unknown Source) and I dont know exactly why. Why shouldnt be Gridlayout's be unknown for Jscrollpane?
Here is the code:
public objectDetails() {
setTitle("LLI_MC_Solver");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
contentPane = new JPanel();
contentPane.setLayout(new GridLayout());
setBounds(100, 100, 510, 401);
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setVisible(true);
contentPane.setPreferredSize(new Dimension(500, 390));
JScrollPane scrollPane = new JScrollPane();
scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
scrollPane.setViewportBorder(new LineBorder(new Color(0, 0, 0), 2));
scrollPane.setBounds(10, 10, 474, 342);
scrollPane.setLayout(new GridLayout(0,4)); //Line which causes the error
scrollPane.setPreferredSize(new Dimension(465, 330));
contentPane.add(scrollPane);
JPanel view = (JPanel)scrollPane.getViewport().getView();
for(Values v : colDetails)
{
JLabel lblC = new JLabel();
lblC.setText(k);
view.add(lblC);
view.validate();
JLabel lblN = new JLabel();
lblN.setText(v.getName());
view.add(lblN);
view.validate();
JLabel lblT = new JLabel();
lblT.setText(v.getType());
view.add(lblT);
view.validate();
JTextField valueBox = new JTextField();
valueBox.setText(v.getValue());
view.add(valueBox);
view.validate();
}
}
I marked the line which causes the Problem according to the compiler. I dont understand why, with the JPanel the same code worked fine. The for-loop where the elements are added I posted for completion purposes, the issue must be somewhere in the setLayout()-Method.
Thanks in advance, appreciate every help.
scrollPane.setLayout(new GridLayout(0,4)); //Line which causes the error
You can't change the layout manager of a scrollpane.
A JScrollPane has its own custom layout manager because it needs to manage the horizontal/vertical scrollbars as well as the row/column headers etc..
Instead you add a panel that uses a GridLayout:
JPanel panel = new JPanel( new GridLayout(0, 4) );
panel.add( component1 );
panel.add( component2 );
panel.add( component3 );
panel.add( component4 );
JScrollPane = new JScrollPane( panel );
I have this code in which I am trying to fit a scrollable Panel (JPanel) but I don't get it. Here is my code:
public class Sniffer_GUI extends JFrame {
Canvas c = new Canvas();
ConnectorPropertiesPanel props;
public Sniffer_GUI() {
super("JConnector demo");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
getContentPane().setLayout(new GridBagLayout());
init();
getContentPane().add(new JLabel("Connectors example. You can drag the connected component to see how the line will be changed"),
new GridBagConstraints(0, 0, 2, 1, 1, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 0, 5), 0, 0));
getContentPane().add(initConnectors(),
new GridBagConstraints(0, 1, 1, 1, 1, 1, GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH, new Insets(5, 5, 5, 5), 0, 0));
getContentPane().add(props,
new GridBagConstraints(1, 1, 1, 1, 0, 1, GridBagConstraints.NORTHWEST, GridBagConstraints.VERTICAL, new Insets(5, 0, 5, 5), 0, 0));
setSize(800, 600);
setLocationRelativeTo(null);
}
Thanks in advance.
I edit to add a code that partially seems to work...
public Sniffer_GUI() {
super("JConnector demo");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel container = new JPanel();
JScrollPane scrPane = new JScrollPane(container);
add(scrPane);
scrPane.setLayout(new ScrollPaneLayout());
init();
add(initConnectors());
setSize(800, 600);
setLocationRelativeTo(null);
}
But it isn't still scrollable, at least it makes its function inside a JScrollPane, is a good step.
Make a JPanel scrollable and use it as a container, something like this:
JPanel container = new JPanel();
JScrollPane scrPane = new JScrollPane(container);
add(scrPane); // similar to getContentPane().add(scrPane);
// Now, you can add whatever you want to the container
To extend #Eng.Fouad answer:
public class Sniffer_GUI extends JFrame {
Canvas c = new Canvas();
ConnectorPropertiesPanel props;
public Sniffer_GUI() {
super("JConnector demo");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel container = new JPanel();
JScrollPane scrPane = new JScrollPane(container);
getContentPane().add(scrPane);
container.setLayout(new GridBagLayout());
init();
container.add(new JLabel("Connectors example. You can drag the connected component to see how the line will be changed"),
new GridBagConstraints(0, 0, 2, 1, 1, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 0, 5), 0, 0));
container.add(initConnectors(),
new GridBagConstraints(0, 1, 1, 1, 1, 1, GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH, new Insets(5, 5, 5, 5), 0, 0));
container .add(props,
new GridBagConstraints(1, 1, 1, 1, 0, 1, GridBagConstraints.NORTHWEST, GridBagConstraints.VERTICAL, new Insets(5, 0, 5, 5), 0, 0));
setSize(800, 600);
setLocationRelativeTo(null);
}
}
Maybe this will help...
JFrame frame = new JFrame();
JPanel panel = new JPanel();
// add something to you panel...
// panel.add(...);
// add the panel to a JScrollPane
JScrollPane jScrollPane = new JScrollPane(panel);
// only a configuration to the jScrollPane...
jScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
jScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
// Then, add the jScrollPane to your frame
frame.getContentPane().add(jScrollPane);
To make a component of a JFrame scrollable, wrap the component in a JScrollPane:
JScrollPane myJScrollPane = new JScrollPane(myJLabel,
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
and replace mentions of myJLabel with myJScrollPane. Worked for me.
Just chiming in, and feel free to correct me if I'm off base, but using a JScrollPane like that has an unintended consequence of requiring more frequent window resizing.
For example, I had a program where I set up a JFrame-wide scrollpane like that. I also had a JTextArea in a tab in the frame that was the same size as the content pane. This textArea was also in its own scrollpane (this was more of a screwing around project than anything else). When I loaded content from a file to deposit in the textArea, it triggered the scrollbars around the text area.
The result was that my, let's call it the innerScrollPane, was now larger than the JFrame because of the scrollbars, which hadn't been visible before. This then triggered what I'm now going to call the outerScrollPane, to display its scrollbars, which then covered up the inner scrollbars.
This was easily resolved by adding an extra window.pack() argument to the end of my file opening method, but I just wanted to throw this out there. The scrollbars can potentially cover up content in the window if you're not careful. But... well there are a million ways to prevent this problem, so it's not a huge deal. Just something to be aware of.
Try this:
JScrollPane sp = new JScrollPane();
this.add(sp).
sp.add( *GUI elements for your applications.*)
Something like that should work for you. Take a look at this as well: