Question
I'm creating a GUI for a message application. the frame's layout is BorderLayout: chat on the western border, list of users on the Eastern border, and user input on the southern border.
The problems:
The panels aren't adhering to the Borderlayout. When I called method revalidate(), The setMinimumSize() is no longer respected.
Panels with scrolls stretch outside of their border when components are added. I tried adding a maximum size / PreferredSize, but the scroll function stops working. I tried revalidating the JPanel and JScrollPane after every added component, but it had no effect.
Answers
problem n.01 was solved by understanding how different layout manager treat different sizes. BorderLayout requires
setPreferredSize(new Dimension(width,height))
This problem was somewhat a follow-up/related problem. This was fixed by
revaldiate()
the frame,in turn the JScrollPane, after every single component added.
Thanks adra :)
I used all the size options I'm aware of, but the JTextArea spill out of its frame.
this.setMinimumSize(new Dimension(width, height));
this.setMaximumSize(new Dimension(width, height));
this.setPreferredSize(new Dimension(width, height));
this.setSize(new Dimension(width, height));
Problem visualized
When running the program without revalidate
problem n.02 after solving problem n.01
GUI code
Frame
package View;
import Control.Controller;
import javax.swing.*;
import java.awt.*;
import static java.awt.Color.*;
public class ChatFrame extends JFrame {
private Controller controller;
private ChatView wp;
private UserList ep;
private UserInput sp;
private int width = 1400;
private int height = 800;
public ChatFrame(){
super("El 3yal");
this.setSize(width, height);
this.setLocation(20,0);
this.getContentPane().setLayout(new BorderLayout(20,20));
this.setResizable(false);
this.setVisible(true);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
setUp();
}
public void setUp(){
wp = new ChatView(1000,600,controller,this);
addScroll(wp, BorderLayout.WEST, 1000, 600);
ep = new UserList(380, 600, controller, this);
addScroll(ep, BorderLayout.EAST, 380, 600);
sp = new UserInput(800, 200, controller, this);
this.add(sp, BorderLayout.SOUTH);
revalidate();
}
public void addScroll(JPanel pnl, String str, int w, int h){
JScrollPane jsp = new JScrollPane(pnl);
jsp.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
jsp.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
jsp.setSize(new Dimension(w, h));
jsp.getVerticalScrollBar().setUnitIncrement(16);
jsp.setBorder(BorderFactory.createLineBorder(Color.black));
this.add(jsp, str);
}
public Controller getController() {
return controller;
}
public ChatView getWp() {
return wp;
}
public UserList getEp() {
return ep;
}
public UserInput getsPnl() {
return sp;
}
}
class test{
public static void main(String[] args){
ChatFrame frame = new ChatFrame();
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
frame.getWp().receive("hadsag", "Hello i want to say hi", null);
for(int i = 0; i < 15; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
frame.getWp().receive("Hadsag", "Hello i want to say hi", new ImageIcon("files/icon.jpeg"));
}
}
});
thread.start();
}
}
chat view panel
package View;
import Control.Controller;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.awt.*;
public class ChatView extends JPanel {
private ChatFrame frame;
private Controller controller;
private int width;
private int height;
public ChatView(int width, int height, Controller controller, ChatFrame frame) {
super();
this.frame = frame;
this.controller = controller;
this.width = width;
this.height = height;
setUp();
}
public void setUp(){
this.setMinimumSize(new Dimension(width, height));
this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
this.setBorder(BorderFactory.createLineBorder(Color.black));
}
public void receive(String name, String txt, ImageIcon pic){
Box box = Box.createHorizontalBox();
box.setMinimumSize(new Dimension(600, 170));
box.setSize(new Dimension(600, 170));
TextArea lblText = new TextArea("< " + name + " > : " + txt);
lblText.setEditable(false);
lblText.setFont(new Font("Serif", Font.PLAIN, 12));
lblText.setMinimumSize(new Dimension(400, 20));
lblText.setMaximumSize(new Dimension(600, 170));
box.add(lblText, LEFT_ALIGNMENT);
JLabel lblPic = new JLabel();
lblPic.setMinimumSize(new Dimension(100, 150));
lblPic.setMaximumSize(new Dimension(100, 150));
if(pic != null) {
Image image = pic.getImage();
image = image.getScaledInstance(100, 150, java.awt.Image.SCALE_SMOOTH);
pic = new ImageIcon(image);
lblPic.setIcon(pic);
}
box.add(lblPic, RIGHT_ALIGNMENT);
this.add(box);
/*
TextArea chatText = new TextArea();
chatText.setEditable(false);
chatText.append("< "+name+" > : " + txt);
chatText.setFont(new Font("Serif", Font.PLAIN, 10));
chatText.setMinimumSize(new Dimension(600,20));
chatText.setMaximumSize(new Dimension(600,60));
this.add(chatText, LEFT_ALIGNMENT);
this.add(Box.createRigidArea(new Dimension(0,5)));
Image image = pic.getImage();
image = image.getScaledInstance(100, 150, java.awt.Image.SCALE_SMOOTH);
pic = new ImageIcon(image);
JLabel lblPic = new JLabel();
lblPic.setIcon(pic);
lblPic.setMinimumSize(new Dimension(600,150));
lblPic.setMaximumSize(new Dimension(600,250));
this.add(lblPic, LEFT_ALIGNMENT);
*/
this.add(Box.createRigidArea(new Dimension(0,5)));
this.revalidate();
}
}
user List
package View;
import Control.Controller;
import javax.swing.*;
import java.awt.*;
public class UserList extends JPanel {
private ChatFrame frame;
private Controller controller;
private int width;
private int height;
private JLabel lblUsers;
public UserList(int width, int height, Controller controller, ChatFrame frame) {
super(null);
this.frame = frame;
this.controller = controller;
this.width = width;
this.height = height;
this.setSize(width, height);
this.setBorder(BorderFactory.createLineBorder(Color.black));
this.setLayout(new BoxLayout(this,BoxLayout.PAGE_AXIS));
setUp();
addComponents();
}
public void setUp(){
this.setMinimumSize(new Dimension(width, height));
this.setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
this.setBorder(BorderFactory.createLineBorder(Color.black));
}
public void addComponents(){
lblUsers = new JLabel("Users");
this.setMinimumSize(new Dimension(50,50));
this.add(lblUsers);
}
}
**User Input Panel**
package View;
import Control.Controller;
import javax.swing.*;
import javax.swing.filechooser.FileFilter;
import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
public class UserInput extends JPanel {
private ChatFrame frame;
private Controller controller;
private int width;
private int height;
private JButton pic, send;
private JTextArea message;
public UserInput(int width, int height, Controller controller, ChatFrame frame) {
super();
this.frame = frame;
this.controller = controller;
this.width = width;
this.height = height;
this.setSize(width, height);
setUp();
addComponents();
}
public void setUp(){
this.setMinimumSize(new Dimension(width, height));
this.setLayout(new FlowLayout());
this.setBorder(BorderFactory.createLineBorder(Color.black));
}
public void addComponents(){
pic = new JButton("attach image");
pic.setMinimumSize(new Dimension(200,200));
pic.addActionListener(l->changePP());
this.add(pic);
message = new JTextArea("write here!");
message.setMinimumSize(new Dimension(400,200));
this.add(message);
send = new JButton("send");
send.setMinimumSize(new Dimension(200,200));
send.addActionListener(l->sendMessage());
this.add(send);
revalidate();
}
public void sendMessage(){
}
private void changePP() {
JFileChooser fileChooser = new JFileChooser();
fileChooser.setAcceptAllFileFilterUsed(false);
fileChooser.addChoosableFileFilter(new FileFilter() {
@Override
public boolean accept(File f) {
String filename = f.getName();
if (f.isDirectory()) {
return true;
} else if (filename.endsWith("jpg'") || filename.endsWith("jpeg") || filename.endsWith("png") || filename.endsWith("gif")) {
return true;
} else {
return false;
}
}
@Override
public String getDescription() {
return "Images";
}
});
int option = fileChooser.showOpenDialog(frame);
if(option == JFileChooser.APPROVE_OPTION){
File sourceFile = fileChooser.getSelectedFile();
String extension = "";
int i = sourceFile.getAbsolutePath().lastIndexOf('.');
if (i > 0) {
extension = sourceFile.getAbsolutePath().substring(i+1);
}
File destinationFile = new File("files/sent." + extension);
try {
Files.copy(sourceFile.toPath(),destinationFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
} catch (IOException e) {
e.printStackTrace();
}
pic.setIcon(new ImageIcon("files/sent." + extension));
}else{
JOptionPane.showMessageDialog(null, "Error selecting image");
}
}
}