英文:
Cant make my JButtons responsives. Everything resize except for that panel
问题
以下是翻译后的代码部分:
public class StackOverflow {
public static void main(String[] args) {
Producto.crearProductosInicio();
Categoria.crearCategorias();
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
PantallaGeneral fondo = new PantallaGeneral();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
class ProductPane extends JScrollPane {
static JPanel contenedorPanelProductos = new JPanel();
JPanel panelProductos;
public ProductPane() {
super(
contenedorPanelProductos,
ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED
);
this.setLayout(new ScrollPaneLayout());
panelProductos = new JPanel();
}
public void dibujarProductos(int categoria, TicketPane ticketMesa) {
ArrayList<Categoria> categorias = Categoria.listaCategorias()
.stream()
.filter(x -> x.getIDPadre() == categoria)
.collect(Collectors.toCollection(ArrayList::new));
ArrayList<Producto> productos = Producto.listaProductos()
.stream()
.filter(x -> x.getID_Categoria() == categoria)
.collect(Collectors.toCollection(ArrayList::new));
panelProductos.removeAll();
panelProductos.updateUI();
JButton botones;
panelProductos.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.anchor = GridBagConstraints.FIRST_LINE_START;
c.weightx = 1.0;
c.weighty = 1.0;
c.ipadx = 0;
c.ipady = 0;
panelProductos.setBackground(Color.yellow);
int x = 0, y = 0;
for (int i = 0; i < categorias.size(); i++) {
botones = categorias.get(i).getBoton();
int finalI = i;
botones.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
dibujarProductos(categorias.get(finalI).getID(), ticketMesa);
}
});
c.gridx = x;
c.gridy = y;
x++;
if (x == 12) {
x -= 12;
y++;
}
c.anchor = GridBagConstraints.FIRST_LINE_START;
panelProductos.add(botones, c);
}
for (int i = 0; i < productos.size(); i++) {
botones = productos.get(i).getBoton();
c.gridx = x;
c.gridy = y;
x++;
if (x == 12) {
x -= 12;
y++;
}
panelProductos.add(botones, c);
}
if (categoria > 1) {
botones = new JButton("General");
botones.setMargin(new Insets(0, 0, 0, 0));
Font fuente = new Font("Arial", 1, 10);
botones.setFont(fuente);
botones.setBackground(Color.white);
botones.setPreferredSize(
new Dimension(
(
(
(
java.awt.Toolkit.getDefaultToolkit().getScreenSize().width / 2
) - 40
) / 12
),
(
(
(
Toolkit.getDefaultToolkit().getScreenSize().width / 2
) - 40
) / 12
)
)
);
botones.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
dibujarProductos(1, ticketMesa);
}
});
c.gridx = x;
c.gridy = y;
x++;
if (x == 12) {
x -= 12;
y++;
}
panelProductos.add(botones, c);
}
agregarPanel(panelProductos);
}
public void agregarPanel(JPanel panelProductos) {
contenedorPanelProductos.setBackground(Color.BLUE);
contenedorPanelProductos.setBorder(
BorderFactory.createEmptyBorder(10, 20, 10, 20)
);
contenedorPanelProductos.setLayout(new GridBagLayout());
GridBagConstraints v = new GridBagConstraints();
v.weightx = 1;
v.weighty = 1;
v.anchor = GridBagConstraints.FIRST_LINE_START;
contenedorPanelProductos.add(panelProductos, v);
}
}
由于您要求只返回代码部分的翻译,我已经将代码部分进行了翻译处理。如果您对翻译结果有任何疑问或需要进一步的帮助,请随时提问。
英文:
I've been thinking for days trying to make my UI responsive, but I'm learning and cant find a way by myself.
This is what i want to do, as the img, but responsive (always showing the same number of buttons in that JScrollPanel). I set the starting size taking the actual screenSize, and it start maximized, so it starts with a 12 buttons column.
https://i.ibb.co/9hTwsh1/image.png
But when I resize it, my buttons don't, so my buttons panels stay the same size, when the rest of my program resize:
https://i.ibb.co/NFHvfLr/image.png
(cant expand imgs, maybe someone can edit this for me? thanks in advance)
The main problem I got is that I don't know how many buttons I'll need so I tried to do a dynamic and responsive layouts but don't know how to do it with my buttons.
EDIT-1:
I have made some changes since yesterday, and because of your comments (thanks a lot).
-
You told me to use GridLayout instead of GridBagLayout. I change to gridBag trying to achieve the responsive UI, but it didnt work. I roll back to GridLayout as you said... at least is cleaner.
-
I also made a reproducible example as you told me to do. About the coments, ill delete them. As you comment, is only noise (those are only for me, ideas). Sorry, should delete them before i post the first time.
-
About the change to a comboBox, im trying to simulate a POS program, so i need those big buttons
-
About the 4th comment.. I search about what you said of updateUI... The problem is that i use that because when i do mainPanel.removeAll(), it dont work unless i do "updateUI" after that(yo can see I use that like 4 times in my program). How should I update my panels after removeAll? - Just look for a solution. Maybe with revalidate is the correct way to do this?
You told me too not to use setPreferredSize.. but i need my buttons to be always the same(if maximized, resizable if not). No matter if i draw 10 or 100. How should i do that without preferredSize?
And about statics.. the truth is that i use statics when i dont know how to do it otherwise. But, as you say, ill try to change that.
New code (trying to do it shorter, but as you can see, im not good at this yet =) ):
public class StackOverflow {
public static void main(String[] args) {
Producto.crearProductosInicio();
Categoria.crearCategorias();
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
PantallaGeneral fondo = new PantallaGeneral();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
class ProductPane extends JScrollPane {
static JPanel contenedorPanelProductos = new JPanel();
static JPanel panelProductos;
public ProductPane () {
super(
contenedorPanelProductos,
ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED
);
this.setLayout(new ScrollPaneLayout());
panelProductos=new JPanel();
}
public static void dibujarProductos ( int categoria) {
ArrayList<Categoria> categorias = Categoria.listaCategorias().stream().filter(x->x.getIDPadre()==categoria).collect(Collectors.toCollection(ArrayList::new));
ArrayList<Producto> productos = Producto.listaProductos().stream().filter(x->x.getID_Categoria()==categoria).collect(Collectors.toCollection(ArrayList::new));
panelProductos.removeAll();
panelProductos.updateUI();
JButton botones;
panelProductos.setLayout(new GridLayout(0,12));
panelProductos.setBackground(Color.yellow);
int x=0 ,y=0;
for (int i = 0; i<categorias.size();i++) {
botones=categorias.get(i).getBoton();
panelProductos.add(botones);
}
for (int i = 0; i<productos.size();i++) {
botones=productos.get(i).getBoton();
panelProductos.add(botones);
}
if (categoria>1) {
botones = crearCategoriaGeneral();
panelProductos.add(botones);
}
agregarPanel(panelProductos);
}
public static JButton crearCategoriaGeneral () {
JButton botonGeneral = new JButton("General");
botonGeneral.setMargin(new Insets(0, 0, 0, 0));
Font fuente = new Font("Arial",1,10);
botonGeneral.setFont(fuente);
botonGeneral.setBackground(Color.white);
botonGeneral.setPreferredSize(new Dimension((((java.awt.Toolkit.getDefaultToolkit().getScreenSize().width/2)-40)/12),(((Toolkit.getDefaultToolkit().getScreenSize().width/2)-40)/12)));
botonGeneral.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
dibujarProductos(1);
}
});
return botonGeneral;
}
public static void agregarPanel (JPanel panelProductos) {
contenedorPanelProductos.setBackground(Color.BLUE);
contenedorPanelProductos.setBorder(BorderFactory.createEmptyBorder(10, 20, 10, 20));
contenedorPanelProductos.setLayout(new GridBagLayout());
GridBagConstraints v = new GridBagConstraints();
v.weightx = 1;
v.weighty = 1;
v.anchor=GridBagConstraints.FIRST_LINE_START;
contenedorPanelProductos.add(panelProductos,v);
}
}
class Producto {
int id;
String nombre;
String rutaImagen;
double precio;
int ID_Categoria;
int ID_Impuesto;
JButton boton;
//Consulta a BD para creación de productos:
static ArrayList<Producto> productos = new ArrayList<>();
public Producto(int id, String nombre, String rutaImagen, double precio, int ID_Categoria, int ID_Impuesto) {
this.id = id;
this.nombre = nombre;
this.rutaImagen = rutaImagen;
this.precio = precio;
this.ID_Categoria = ID_Categoria;
this.ID_Impuesto = ID_Impuesto;
establecerBoton();
}
private void establecerBoton() {
boton = new JButton(this.nombre);
boton.setMargin(new Insets(0, 0, 0, 0));
boton.setBackground(Color.DARK_GRAY);
Font fuente = new Font("Arial", 1, 10);
boton.setFont(fuente);
Dimension tamBot = new Dimension((((java.awt.Toolkit.getDefaultToolkit().getScreenSize().width / 2) - 40) / 12), (((Toolkit.getDefaultToolkit().getScreenSize().width / 2) - 40) / 12));
boton.setPreferredSize(tamBot);
Producto temp = this;
boton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
TicketPane.añadirProductoTicket(temp);
}
});
}
public JButton getBoton() {
return boton;
}
public static ArrayList<Producto> listaProductos () {
return productos;
}
public static void crearProductosInicio() {
for (int i=0;i<15;i++) {
productos.add(new Producto(i, "Aquarius"," ", 0.30*i, 4, 1));
}
for (int i=15;i<75;i++) {
productos.add(new Producto(i, "7up"," ", 0.15*i, 2, 1));
}
}
public int getID_Categoria() {
return ID_Categoria;
}
public String getNombre() {
return nombre;
}
public double getPrecio() {
return precio;
}
}
class Categoria {
static ArrayList<Categoria> categorias = new ArrayList<>();
int ID;
String nombre;
int IDPadre;
JButton boton;
public Categoria(int ID, String nombre, int IDPadre) {
this.ID = ID;
this.nombre = nombre;
this.IDPadre = IDPadre;
establecerBoton();
}
public static void crearCategorias() {
categorias.add(new Categoria(1, "General", 0));
categorias.add(new Categoria(2, "Bebidas", 1));
categorias.add(new Categoria(3, "Comida", 1));
categorias.add(new Categoria(4, "Refrescos", 2));
}
public static ArrayList<Categoria> listaCategorias() {
return categorias;
}
private void establecerBoton() {
boton = new JButton(this.nombre);
boton.setMargin(new Insets(0, 0, 0, 0));
boton.setBackground(Color.white);
Font fuente = new Font("Arial", 1, 10);
boton.setFont(fuente);
//Con el primero, siempre miden lo mismo ya que referencio la resolución del ordenador. Con el segundo, referencio el tamaño del frame, con lo que si cambio el tamaño, se cambian (no responsive=) )
Dimension tamBot = new Dimension((((java.awt.Toolkit.getDefaultToolkit().getScreenSize().width / 2) - 40) / 12), (((Toolkit.getDefaultToolkit().getScreenSize().width / 2) - 40) / 12));
boton.setPreferredSize(tamBot);
boton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
ProductPane.dibujarProductos(ID);
}
});
}
public int getIDPadre() {
return IDPadre;
}
public JButton getBoton() {
return boton;
}
}
class PantallaGeneral {
JFrame pantalla;
//Container general:
private static JPanel contenedorContenido = new JPanel();
//Salon
private JButton boton1 = new JButton("Mesa 1");
private JButton boton2 = new JButton("Mesa 2");
private JButton boton3 = new JButton("Mesa 3");
private JButton botonB = new JButton("Barra");
//Contenedores ventas
JPanel ventasArriba = new JPanel();
JPanel ventasAbajo = new JPanel();
ProductPane panelProductos = new ProductPane();
TicketPane panelTicket = new TicketPane();
public PantallaGeneral () {
Producto.crearProductosInicio();
initPantalla();
dibujarPantallaVenta(0);
}
private void initPantalla () {
pantalla = new JFrame();
pantalla.setLayout(new BorderLayout());
//pantalla.setBounds(0,0,ancho,alto);
pantalla.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pantalla.setResizable(true);
pantalla.setExtendedState(JFrame.MAXIMIZED_BOTH);
pantalla.setVisible(true);
pantalla.getContentPane().add(contenedorContenido,BorderLayout.CENTER);
}
private void dibujarPantallaVenta (int numeroMesa) {
limpiarPantalla();
panelTicket.setPreferredSize(new Dimension(java.awt.Toolkit.getDefaultToolkit().getScreenSize().width / 2, Toolkit.getDefaultToolkit().getScreenSize().height / 2));
panelProductos.setPreferredSize(new Dimension(java.awt.Toolkit.getDefaultToolkit().getScreenSize().width / 2, Toolkit.getDefaultToolkit().getScreenSize().height / 2));
ventasArriba.setPreferredSize(new Dimension(java.awt.Toolkit.getDefaultToolkit().getScreenSize().width, Toolkit.getDefaultToolkit().getScreenSize().height / 2));
ventasAbajo.setPreferredSize(new Dimension(java.awt.Toolkit.getDefaultToolkit().getScreenSize().width, Toolkit.getDefaultToolkit().getScreenSize().height / 2));
contenedorContenido.setLayout(new BoxLayout(contenedorContenido, BoxLayout.Y_AXIS));
contenedorContenido.add(ventasArriba);
contenedorContenido.add(ventasAbajo);
ventasArriba.setLayout(new BoxLayout(ventasArriba, BoxLayout.X_AXIS));
ventasArriba.add(panelTicket);
ventasArriba.add(panelProductos);
panelTicket.dibujarTicket(numeroMesa);
panelProductos.dibujarProductos(1);
}
public void limpiarPantalla () {
contenedorContenido.removeAll();
contenedorContenido.updateUI();
System.gc();
}
}
class TicketPane extends JPanel {
static TreeMap<Integer, DefaultTableModel> tickets=new TreeMap<>();
static int mesaActual=0;
JTable tablaTicket = new JTable();
public TicketPane () {
}
public void dibujarTicket (int numeroMesa) {
removeAll();
updateUI();
tablaTicket.removeAll();
tablaTicket.updateUI();
mesaActual=numeroMesa;
setLayout(null);
setBackground(Color.lightGray);
//setBounds(0,0,PantallaGeneral.ancho/2,PantallaGeneral.alto/2);
if (tickets.get(mesaActual)==null) {
tickets.put(mesaActual,new ModeloTabla());
tickets.get(mesaActual).setColumnIdentifiers(new Object[] { "Producto","Precio"});
}
//tablaTicket.setBounds(0+(int)(PantallaGeneral.ancho/2*0.05),0+(int)(PantallaGeneral.alto/2*0.05),PantallaGeneral.ancho/2-(int)(PantallaGeneral.ancho/2*0.10),PantallaGeneral.alto/2-(int)(PantallaGeneral.alto/2*0.10));
tablaTicket.setVisible(true);
tablaTicket.setModel(tickets.get(mesaActual));
tablaTicket.addMouseListener(new MouseAdapter()
{
public void mouseClicked(MouseEvent e)
{
int fila = tablaTicket.rowAtPoint(e.getPoint());
System.out.println("Se selecciono la fila: " + fila);
}
});
tablaTicket.getColumn("Producto").setPreferredWidth(this.getWidth()-(int)(this.getWidth()*0.15));
javax.swing.JScrollPane jScrollPane1;
jScrollPane1 = new javax.swing.JScrollPane();
jScrollPane1.setViewportView(tablaTicket);
//add(tablaTicket);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 388, Short.MAX_VALUE)
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 288, Short.MAX_VALUE)
.addContainerGap())
);
//pantalla.getContentPane().add(this);
updateUI();
}
public static void añadirProductoTicket(Producto producto) {
NumberFormat nw = NumberFormat.getInstance(new Locale("en", "EN"));
nw.setMaximumFractionDigits(2);
nw.setMinimumFractionDigits(2);
if (tickets.get(mesaActual).getRowCount()==0){
tickets.get(mesaActual).addRow(new Object[] {producto.getNombre(),nw.format(producto.getPrecio())});
tickets.get(mesaActual).addRow(new Object[] {"Total Ticket: ",nw.format(producto.getPrecio())});
}
else {
double total=Double.parseDouble( tickets.get(mesaActual).getValueAt(tickets.get(mesaActual).getRowCount()-1,tickets.get(mesaActual).getColumnCount()-1).toString());
tickets.get(mesaActual).removeRow(tickets.get(mesaActual).getRowCount()-1);
tickets.get(mesaActual).addRow(new Object[] {producto.getNombre(),nw.format(producto.getPrecio())});
total+=producto.getPrecio();
tickets.get(mesaActual).addRow(new Object[] {"Total Ticket: ",nw.format(total)});
}
}
public void calcularTotal () {
}
public static int getMesaActual() {
return mesaActual;
}
}
class ModeloTabla extends DefaultTableModel {
public boolean isCellEditable(int row, int column) {
return false;
}
}
code before 1st edit:
//Main sales drawing
private void dibujarPantallaVenta (int numeroMesa) {
limpiarPantalla();
panelTicket.setPreferredSize(new Dimension(java.awt.Toolkit.getDefaultToolkit().getScreenSize().width/2, Toolkit.getDefaultToolkit().getScreenSize().height/2));
panelProductos.setPreferredSize(new Dimension(java.awt.Toolkit.getDefaultToolkit().getScreenSize().width/2, Toolkit.getDefaultToolkit().getScreenSize().height/2));
ventasArriba.setPreferredSize(new Dimension(java.awt.Toolkit.getDefaultToolkit().getScreenSize().width, Toolkit.getDefaultToolkit().getScreenSize().height/2));
ventasAbajo.setPreferredSize(new Dimension(java.awt.Toolkit.getDefaultToolkit().getScreenSize().width, Toolkit.getDefaultToolkit().getScreenSize().height/2));
pantalla.getContentPane().add(contenedorContenido,BorderLayout.CENTER);
contenedorContenido.setLayout(new BoxLayout(contenedorContenido,BoxLayout.Y_AXIS));
contenedorContenido.add(ventasArriba);
contenedorContenido.add(ventasAbajo);
ventasArriba.setLayout(new BoxLayout(ventasArriba,BoxLayout.X_AXIS));
ventasArriba.add(panelTicket);
ventasArriba.add(panelProductos);
panelTicket.dibujarTicket(numeroMesa); //Dibujo el ticket del numero de mesa indicado
panelProductos.dibujarProductos(1,panelTicket); //Siempre que se abre una mesa, se pinta la categoria general por defecto
}
public class ProductPane extends JScrollPane {
static JPanel contenedorPanelProductos = new JPanel();
JPanel panelProductos;
public ProductPane () {
super(
contenedorPanelProductos,
ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED
);
this.setLayout(new ScrollPaneLayout());
panelProductos=new JPanel();
}
//This is where i paint my JButtons:
public void dibujarProductos ( int categoria,TicketPane ticketMesa) {
//Pendiente: Establecer un tamaño inicial para los botones. Permitir agrandar y achicar este tamaño, asi como el numero de columnas para un ajuste personalizado
ArrayList<Categoria> categorias = Categoria.listaCategorias().stream().filter(x->x.getIDPadre()==categoria).collect(Collectors.toCollection(ArrayList::new));
ArrayList<Producto> productos = Producto.listaProductos().stream().filter(x->x.getID_Categoria()==categoria).collect(Collectors.toCollection(ArrayList::new));
panelProductos.removeAll();
panelProductos.updateUI();
JButton botones;
panelProductos.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.anchor = GridBagConstraints.FIRST_LINE_START;
c.weightx = 1.0;
c.weighty = 1.0;
c.ipadx = 0;
c.ipady = 0;
panelProductos.setBackground(Color.yellow);
int x=0 ,y=0;
for (int i = 0; i<categorias.size();i++) {
botones=categorias.get(i).getBoton();
int finalI = i;
botones.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
dibujarProductos(categorias.get(finalI).getID(),ticketMesa);
}
});
c.gridx = x;
c.gridy = y;
x++;
if (x==12){
x-=12;
y++;
}
c.anchor = GridBagConstraints.FIRST_LINE_START;
panelProductos.add(botones ,c);
}
for (int i = 0; i<productos.size();i++) {
botones=productos.get(i).getBoton();
c.gridx = x;
c.gridy = y;
x++;
if (x==12){
x-=12;
y++;
}
panelProductos.add(botones ,c);
}
if (categoria>1) {
botones = new JButton("General");
botones.setMargin(new Insets(0, 0, 0, 0));
Font fuente = new Font("Arial",1,10);
botones.setFont(fuente);
botones.setBackground(Color.white);
botones.setPreferredSize(new Dimension((((java.awt.Toolkit.getDefaultToolkit().getScreenSize().width/2)-40)/12),(((Toolkit.getDefaultToolkit().getScreenSize().width/2)-40)/12)));
botones.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
dibujarProductos(1,ticketMesa);
}
});
c.gridx = x;
c.gridy = y;
x++;
if (x==12){
x-=12;
y++;
}
panelProductos.add(botones ,c);
}
agregarPanel(panelProductos);
}
public void agregarPanel (JPanel panelProductos) {
contenedorPanelProductos.setBackground(Color.BLUE);
contenedorPanelProductos.setBorder(BorderFactory.createEmptyBorder(10, 20, 10, 20));
contenedorPanelProductos.setLayout(new GridBagLayout());
GridBagConstraints v = new GridBagConstraints();
v.weightx = 1;
v.weighty = 1;
v.anchor=GridBagConstraints.FIRST_LINE_START;
contenedorPanelProductos.add(panelProductos,v);
}
I use panelProductos because if i dont, when i add my buttons they seem to have same padding i coudlnt fix other way
Actual IU:
Without panelProductos:
答案1
得分: 1
希望我理解您想要做的事情。您不希望水平滚动条出现。修复方法非常简单。更改 ProductPane
类的构造函数。以下只是需要更改的部分,上下文是在代码中的位置。
class ProductPane {
public ProductPane() {
super(contenedorPanelProductos,
ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
}
}
在您的原始代码中,您使用了 HORIZONTAL_SCROLLBAR_AS_NEEDED
。这是默认设置,所以您不必显式设置它。但是您不想要水平滚动条出现,所以改用 HORIZONTAL_SCROLLBAR_NEVER
。尝试一下,自己看看效果。如果不起作用,请告诉我,我会删除这个回答。
英文:
Hopefully, I understand what you want to do. You don't want the horizontal scrollbar to appear at all. The fix is quite simple. Change the constructor of class ProductPane
. Below is just the part that needs to be changed in the context of where it is in the code.
class ProductPane {
public ProductPane() {
super(contenedorPanelProductos,
ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
}
}
In your original code, you used HORIZONTAL_SCROLLBAR_AS_NEEDED
. This is the default and so you don't have to explicitly set it. But you don't want the horizontal scrollbar to appear, so use HORIZONTAL_SCROLLBAR_NEVER
instead. Try it and see for yourself. If it doesn't work, let me know and I will delete this answer.
答案2
得分: 0
好的,以下是您提供的内容的翻译:
我想我理解你想要做的事情。我完全不知道你的GUI底部面板是做什么的。
我尝试运行你的代码并遇到了问题。当我尝试减小GUI的大小时,GUI会从我的显示器上消失。按钮会消失然后重新出现。
我从零开始创建了一个POS模拟器GUI。我不得不使用一些Swing的技巧,我将会更详细地解释。
这是GUI的样子。
(图片已省略)
当你扩展GUI以填满屏幕时,按钮会移动位置以填充空间。收银纸带面板的大小保持不变。
通常,在创建Swing GUI时,你尽量让它尽可能小。当你扩展GUI的大小时,比试图将GUI缩小以适应特定的监视器要容易得多。
我决定为收银显示使用JTextArea以节省更多的GUI空间。
我从简单的开始。我首先创建了JFrame
、Item
和Inventory
类。Item
类保存项目的名称和价格,而Inventory
类保存多个项目。我将项目价格保存为分,这样我就可以进行整数算术,而不必担心舍入误差。
我删除了所有静态的Swing组件、字段和方法。相对于处理静态字段的副作用,跟踪实例要容易得多。
我使用了Swing组件,但没有扩展任何Swing组件。当你想要覆盖类的某个方法时,才应该扩展Swing组件或任何Java类。
我逐步构建了这个GUI,每次编码一个小片段都会进行测试。我很少在运行一个或多个测试之前添加超过20到30行的代码。我无法编写500行代码并都做正确。
我编写了6个类。POSSimulator
类持有JFrame
。其余的类都是内部类,这样我就可以将代码作为一个完整的、可执行的示例发布。
ButtonPanel
类创建了按钮面板。RegisterPanel
类创建了收银纸带面板。ButtonListener
类实现了ActionListener
接口,并为按钮提供功能。
Inventory
类持有库存。Item
类持有一个项目。
每个类都按照其类名所表示的功能进行操作。你的GUI越大,每个类只做一件事情就越重要。
ButtonPanel
类创建了一个外部的JPanel
,其中包含一个JScrollPane
,里面包含一个内部的JPanel
,内部的JPanel
包含单独的按钮JPanels
。这听起来很复杂,但它允许外部的JPanel
增长,而单独的按钮JPanels
保持其大小。
我创建了40个按钮。我只为库存创建了4个项目,所以我重复了库存10次。你需要根据库存中的项目数量调整createPanel
方法中的代码,以创建与库存中的项目数量相等的按钮。
根据你设置的JButtons
的首选大小,你需要调整JPanel
的首选大小。关于不设置首选大小的评论是针对普通GUI的。在我理解你的特殊应用之前,我无法理解你试图做什么。
RegisterPanel
类更加直观。appendItem
方法向收银纸带面板追加项目。我使用String
类的format
方法来格式化项目的名称和价格,以及总价。
ButtonListener
类从JButton
获取项目的名称,查找库存中的项目,并调用RegisterPanel
类的appendItem
方法。
Inventory
和Item
类是普通的Java类,分别用于保存库存和项目。
以下是代码:
(代码已省略)
英文:
I think I understand what you're trying to do. I have no idea what the bottom panel of your GUI does.
I tried running your code and had problems. The GUI would disappear from my monitor when I tried to reduce the size of the GUI. The buttons would disappear and reappear.
I created a POS Simulator GUI from scratch. I had to use a few Swing tricks, which I'll explain in more detail.
Here's the GUI.
When you expand the GUI to fill the screen, the buttons shift position to fill the space. The register tape panel stays the same size.
In general, when you create a Swing GUI, you try to make it as small as possible. It's a lot easier to see what happens when you expand the size of the GUI than trying to shrink the GUI to fit on a particular monitor.
I decided to use a JTextArea for the register display to save more GUI space.
I started simple. I created the JFrame
and the Item
and Inventory
classes first. The Item
class holds the name and price of an item, while the Inventory
class holds multiple items. I saved the item price in pennies so that I could do integer arithmetic and not worry about rounding errors.
I removed all static Swing components, fields, and methods. It's a lot easier to keep track of instances than to deal with the side effects of static fields.
I used Swing components. I did not extend any Swing components. The only time you should extend a Swing component, or any Java class, is when you want to override one of the class methods.
I built this GUI one small piece at a time, testing each piece as I coded it. I rarely added more than 20 to 30 lines of code before running one or more tests. There's no way I could write 500 lines of code and get them all correct.
I wrote 6 classes. The POSSimulator
class holds the JFrame
. I made the remainder of the classes inner classes so I could post the code as a complete, executable example.
The ButtonPanel
class creates the button panel. The RegisterPanel
class creates the register tape panel. The ButtonListener
class implements ActionListener
and gives the buttons their function.
The Inventory
class holds the inventory. The Item
class holds an item.
Each class does what the name of the class says it does. The larger your GUI, the more important that each class does one thing and one thing well.
The ButtonPanel
class creates an outer JPanel
, which contains a JScrollPane
, which contains an inner JPanel
, which contains individual button JPanels
. This sounds complicated, but it allows the outer JPanel
to grow and for the individual button JPanels
to maintain their size.
I created 40 buttons. I only created 4 items for the inventory, so I repeated the inventory 10 times. You would want to adjust the code in the createPanel
method to create one button for each item in the inventory.
You're going to have to play with the JPanel
preferred sizes depending on what preferred size you make the JButtons
. The advice in the comments about not setting a preferred size is for ordinary GUIs. Your GUI is a special application that I didn't understand until you further explained what you were trying to do.
The RegisterPanel
class is more straightforward. The appendItem
method appends an item to the register tape panel. I use the format
method of the String
class to format the name and price of the item, as well as the total price.
The ButtonListener
class gets the name of the item from the JButton
, looks up the item in the inventory, and calls the appendItem
method of the RegisterPanel
class.
The Inventory
and Item
classes are plain Java classes to hold the inventory and item, respectively.
Here's the code.
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
public class POSSimulator implements Runnable {
public static void main(String[] args) {
SwingUtilities.invokeLater(new POSSimulator());
}
private ButtonPanel buttonPanel;
private Inventory inventory;
private JFrame frame;
private RegisterPanel registerPanel;
public POSSimulator() {
this.inventory = new Inventory();
}
@Override
public void run() {
frame = new JFrame("POS Si8mulator");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
registerPanel = new RegisterPanel();
frame.add(registerPanel.getPanel(),
BorderLayout.BEFORE_LINE_BEGINS);
buttonPanel = new ButtonPanel();
frame.add(buttonPanel.getPanel(), BorderLayout.CENTER);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public class ButtonPanel {
private JPanel panel;
public ButtonPanel() {
createPanel();
}
private void createPanel() {
panel = new JPanel(new BorderLayout());
panel.setPreferredSize(new Dimension(360, 600));
JPanel innerPanel = new JPanel(new FlowLayout(
FlowLayout.LEADING));
innerPanel.setPreferredSize(new Dimension(340, 2320));
ButtonListener listener = new ButtonListener();
List<Item> items = inventory.getInventory();
int size = items.size();
int j = 0;
// We're creating more buttons than inventory
for (int i = 0; i < 40; i++) {
JPanel buttonPanel = createButtonPanel(
items.get(j), listener);
innerPanel.add(buttonPanel);
j++;
j = (j >= size) ? 0 : j;
}
JScrollPane scrollPane = new JScrollPane(innerPanel);
panel.add(scrollPane, BorderLayout.CENTER);
}
private JPanel createButtonPanel(Item item,
ButtonListener listener) {
JPanel panel = new JPanel(new BorderLayout());
panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
JButton button = new JButton(item.getName());
button.addActionListener(listener);
button.setPreferredSize(new Dimension(150, 100));
panel.add(button, BorderLayout.CENTER);
return panel;
}
public JPanel getPanel() {
return panel;
}
}
public class RegisterPanel {
private int total;
private JPanel panel;
private JTextArea textArea;
private String totalString;
public RegisterPanel() {
this.totalString = "Register total";
setTotal(0);
createPanel();
}
private void setTotal(int total) {
this.total = total;
}
private void createPanel() {
panel = new JPanel(new BorderLayout());
textArea = new JTextArea(10, 40);
textArea.setText("");
textArea.setFont(new Font(
"Courier New", Font.BOLD, 12));
JScrollPane scrollPane = new JScrollPane(textArea);
panel.add(scrollPane, BorderLayout.CENTER);
}
public void appendItem(Item item) {
int price = item.getPrice();
total += price;
String tape = textArea.getText();
if (!tape.isEmpty()) {
int pos = tape.indexOf(totalString);
tape = tape.substring(0, pos);
}
String line = String.format("%-30s", item.getName());
line += String.format("%7.2f", 0.01d * price);
tape += line + System.lineSeparator();
line = String.format("%-30s", totalString);
line += String.format("%7.2f", 0.01d * total);
tape += line + System.lineSeparator();
textArea.setText(tape);
}
public JPanel getPanel() {
return panel;
}
}
public class ButtonListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent event) {
JButton button = (JButton) event.getSource();
String name = button.getText();
Item item = inventory.getItem(name);
registerPanel.appendItem(item);
}
}
public class Inventory {
private List<Item> inventory;
public Inventory() {
this.inventory = new ArrayList<>();
addInventory();
}
private void addInventory() {
inventory.add(new Item("Coke Zero", "3.33"));
inventory.add(new Item("Sprite Zero", "3.33"));
inventory.add(new Item("Dark Kidney Beans", ".99"));
inventory.add(new Item("Tomato Sauce", "1.19"));
}
public void addItem(Item item) {
inventory.add(item);
}
public Item getItem(String name) {
for (Item item : inventory) {
if (item.getName().equals(name)) {
return item;
}
}
return null;
}
public List<Item> getInventory() {
return inventory;
}
}
public class Item {
private int price;
private String name;
public Item(String name, String price) {
this.name = name;
setPrice(price);
}
public void setPrice(String price) {
Double value = Double.valueOf(price);
this.price = (int) Math.round(100d * value);
}
public int getPrice() {
return price;
}
public String getName() {
return name;
}
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论