gpt4 book ai didi

java - 当包含在 GridBagLayout 中时,如何使我的面板换行文本并增加高度而不是宽度?

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:10:14 25 4
gpt4 key购买 nike

[最终编辑]

好的伙计们。

我不知道为什么它在我的聊天程序中不起作用......但我设法修复了 SSCCE.. 使用它现在可以工作的可滚动实现。谢谢大家!

代码:

package de.sky.cjat;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.LayoutManager;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;

import javax.swing.AbstractAction;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.KeyStroke;
import javax.swing.Scrollable;
import javax.swing.UIManager;

public class MyKskb {

private int row;

class SomethingPanel extends JPanel implements Scrollable {

public SomethingPanel(LayoutManager manager){
super(manager);
}

@Override
public Dimension getPreferredScrollableViewportSize(){
return getPreferredSize();
}

@Override
public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction){
return 5;
}

@Override
public boolean getScrollableTracksViewportHeight(){
return false;
}

@Override
public boolean getScrollableTracksViewportWidth(){
return true;
}

@Override
public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction){
return 1;
}
}

public MyKskb(){
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().setPreferredSize(new Dimension(800, 600));
// final JPanel content = new JPanel(new GridBagLayout());
final SomethingPanel content = new SomethingPanel(new GridBagLayout());

// final JPanel empty = new JPanel();
// empty.setPreferredSize(new Dimension(0, 0));
// GridBagConstraints gbc = new GridBagConstraints();
// content.add(empty, gbc);
content.getInputMap().put(KeyStroke.getKeyStroke("ENTER"), "§");
content.getActionMap().put("§", new AbstractAction(){
@Override
public void actionPerformed(ActionEvent e){
JPanel p = new JPanel(new BorderLayout());
p.setBorder(BorderFactory.createLineBorder(Color.BLACK, 2));
p.setBackground(Color.GRAY);

GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(10, 10, 10, 10);
gbc.weightx = 1.0;
gbc.gridx = 0;
gbc.gridy = row++;
gbc.fill = GridBagConstraints.HORIZONTAL;

// content.remove(empty);
// gbc.gridy = row;
// gbc.weighty = 1.0;
// content.add(empty, gbc);

JTextArea text = new JTextArea(
Math.random() > 0.5 ?
"ABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABC" :
"FFFFFFFFFFFFABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABC");
text.setLineWrap(true);
p.add(text);
content.add(p, gbc);
content.revalidate();
}
});
JScrollPane scrollPane = new JScrollPane(content);
f.pack();
f.setLocationRelativeTo(null);
f.add(scrollPane);
f.setVisible(true);
}

public static void main(String[] args) throws Exception {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
new MyKskb();
}
}

[结束]

[问题]

我正在编写一个聊天程序,布局如下所示:

enter image description here

带有消息的面板有一个 GridBagLayout 并包装在一个 JScrollPane 中。

问题是,如果消息太长,消息面板会拉伸(stretch)并变得太大:

enter image description here

所以我想要实现的是限制面板的大小,它包含在 JScrollPane 中 - 如果文本变长而不是变宽,我希望带有消息文本的灰色面板增加它们的高度。 IE。在不增加面板宽度的情况下包装文本。

有没有办法通过网格包布局实现这一点,还是我遗漏了什么?或者我应该使用另一个布局管理器?

编辑:完整的层次结构:

JScrollPane
JPanel (gbl)
JPanel (custom painting)
JComponent (JLabel but it can vary)
JPanel (custom painting)
JComponent (JLabel but it can vary)
JPanel (custom painting)
JComponent (JLabel but it can vary)
....

编辑:我尝试像这样实现 Scrollable:

@Override
public Dimension getPreferredScrollableViewportSize(){
return new Dimension(100, getHeight());
}

@Override
public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction){
return 5;
}

@Override
public boolean getScrollableTracksViewportHeight(){
return false;
}

@Override
public boolean getScrollableTracksViewportWidth(){
return true;
}

@Override
public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction){
return 1;
}

但如果文本太长,同样的事情会发生...我不知道 getPreferredScrollableViewportSize 应该返回什么,而且 getSize() 也没有用...

编辑:这是一个 SSCCE,它显示了我的 GUI 的基本结构:(按回车键添加新组件)

package de.sky.cjat;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;

import javax.swing.AbstractAction;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.KeyStroke;
import javax.swing.UIManager;

public class Kskb {

private int row;

public Kskb(){
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().setPreferredSize(new Dimension(800, 600));
final JPanel content = new JPanel(new GridBagLayout());
final JPanel empty = new JPanel();
empty.setPreferredSize(new Dimension(0, 0));
GridBagConstraints gbc = new GridBagConstraints();
content.add(empty, gbc);
content.getInputMap().put(KeyStroke.getKeyStroke("ENTER"), "§");
content.getActionMap().put("§", new AbstractAction(){
@Override
public void actionPerformed(ActionEvent e){
JPanel p = new JPanel();
p.setBackground(Color.GRAY);
JLabel text = new JLabel("ABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABC");
p.add(text);

GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(10, 10, 10, 10);
gbc.weightx = 1.0;
gbc.gridy = row++;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.anchor = GridBagConstraints.NORTHWEST;

content.add(p, gbc);

content.remove(empty);
gbc.gridy = row;
gbc.weighty = 1.0;
content.add(empty, gbc);

content.revalidate();
}
});
JScrollPane scrollPane = new JScrollPane(content);
f.pack();
f.setLocationRelativeTo(null);
f.add(scrollPane);
f.setVisible(true);
}

public static void main(String[] args) throws Exception {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
new Kskb();
}
}

最佳答案

根据@durandal 的建议,问题出在 JLabel 上。 JLabel 不换行文本。所以你需要使用不同的组件。这是使用 JTextArea 修改的代码:

import java.awt.*;
import java.awt.event.ActionEvent;

import javax.swing.*;
import javax.swing.border.*;

public class Kskb {

private int row;

public Kskb()
{
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().setPreferredSize(new Dimension(800, 600));
// final JPanel content = new JPanel(new GridBagLayout());
final ScrollablePanel content = new ScrollablePanel(new GridBagLayout());
content.setScrollableWidth( ScrollablePanel.ScrollableSizeHint.FIT );
final GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(10, 10, 10, 10);
gbc.gridx = 0;
gbc.gridy = 0;
gbc.weightx = 1.0;
gbc.fill = GridBagConstraints.HORIZONTAL;
content.getInputMap().put(KeyStroke.getKeyStroke("ENTER"), "");
content.getActionMap().put("", new AbstractAction(){
@Override
public void actionPerformed(ActionEvent e)
{
JPanel p = new JPanel( new BorderLayout() );
p.setBorder( new EmptyBorder(10, 10, 10, 10) );
p.setBackground(Color.GRAY);
JTextArea text = new JTextArea();
text.append("ABCABCABCABCABCABCABCABC ABCABCABCABCABCABCABCABCABCABCABCABCABCABC ABCABCABCABCABCABCABCABCABCABCABCABCABCA BCABCABCABCABCABCABCAB CABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABC");
text.setLineWrap( true );
p.add(text);

gbc.gridy = row++;
content.add(p, gbc);
content.revalidate();
}
});

JScrollPane scrollPane = new JScrollPane(content);
f.pack();
f.setLocationRelativeTo(null);
f.add(scrollPane);
f.setVisible(true);
}

public static void main(String[] args) throws Exception {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
new Kskb();
}
}

关键是 Scrollable 实现,它强制调整面板宽度和调整框架。此代码使用 Scrollable Panel ,它只是 Scrollable 接口(interface)的可重用实现,您可以使用方法对其进行配置,而不是创建新类并重写这些方法。

关于java - 当包含在 GridBagLayout 中时,如何使我的面板换行文本并增加高度而不是宽度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29924478/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com