- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我在使用 JTextArea
时遇到问题。我的实际设置不同,但效果仍然存在。这是问题的图片:
当拥有 JDialog
的大小仅比 JTextArea
所需的首选大小低 1 个像素时,文本区域会突然调整大小。在我的实际设置中,它们突然变高了。我正在使用 GridBagLayout
,但它似乎发生在其他布局中。这是为什么?
下面是重现上述效果的易于编译的代码。
import java.awt.*;
import java.awt.event.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.swing.*;
import javax.swing.text.JTextComponent;
public class TextDemo extends JDialog implements ActionListener {
private static final long serialVersionUID = -589374238138963529L;
protected JTextField textField;
protected JTextArea textArea;
private final static String newline = "\n";
private static final java.awt.Dimension SCREENSIZE =
java.awt.Toolkit.getDefaultToolkit().getScreenSize();
private static final java.awt.Point SCREENCENTER =
new java.awt.Point(SCREENSIZE.width/2,SCREENSIZE.height/2);
public TextDemo(Window owner, String shortMessage, String message, JComponent accessory) {
super(owner);
setTitle("Test");
setDefaultCloseOperation(JDialog.HIDE_ON_CLOSE);
Icon icon = UIManager.getIcon("OptionPane.warningIcon");
JTextArea shortText = makeMultiLineLabel(true);
shortText.setBorder(BorderFactory.createEtchedBorder());
shortText.setFont(shortText.getFont().deriveFont(Font.BOLD));
shortText.setRows(2);
shortText.setColumns(20);
shortText.setText(shortMessage);
JTextArea messageText = makeMultiLineLabel(true);
messageText.setBorder(BorderFactory.createEtchedBorder());
messageText.setFont(shortText.getFont().deriveFont(Font.PLAIN));
messageText.setRows(4);
messageText.setColumns(20);
messageText.setText(message);
JPanel buttonPanel = new JPanel();
buttonPanel.add(new JButton("OK"));
buttonPanel.add(new JButton("Cancel"));
JPanel contentPanel = new JPanel();
contentPanel.setOpaque(true);
contentPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 8, 9));
contentPanel.setLayout(new GridBagLayout());
GridBagConstraints c;
c = new GridBagConstraints();
c.gridx = 0;
c.gridy = 0;
c.anchor = GridBagConstraints.FIRST_LINE_START;
c.gridheight = 2;
contentPanel.add(new JLabel(icon), c);
c = new GridBagConstraints();
c.gridx = 1;
c.gridy = 0;
c.fill = GridBagConstraints.BOTH;
c.weighty = 1.0;
c.weightx = 1.0;
contentPanel.add(shortText, c);
c = new GridBagConstraints();
c.gridx = 1;
c.gridy = 1;
c.fill = GridBagConstraints.BOTH;
c.weighty = 1.0;
c.weightx = 1.0;
contentPanel.add(messageText, c);
if (accessory != null) {
c = new GridBagConstraints();
c.gridx = 0;
c.gridy = 2;
c.gridwidth = 2;
c.fill = GridBagConstraints.BOTH;
c.weighty = 1.0;
c.weightx = 1.0;
contentPanel.add(accessory, c);
}
c = new GridBagConstraints();
c.gridwidth = 2;
c.gridx = 0;
c.gridy = 3;
contentPanel.add(buttonPanel, c);
setContentPane(contentPanel);
}
public void actionPerformed(ActionEvent evt) {
String text = textField.getText();
textArea.append(text + newline);
textField.selectAll();
//Make sure the new text is visible, even if there
//was a selection in the text area.
textArea.setCaretPosition(textArea.getDocument().getLength());
}
/**
* Create the GUI and show it. For thread safety,
* this method should be invoked from the
* event dispatch thread.
*/
private static void createAndShowGUI() {
//Create and set up the window.
JFrame frame = new JFrame("TextDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
try {
throw new Exception("Test");
} catch (Exception e) {
TextDemo t = new TextDemo(frame, "You won't get away with this!",
"Alert! Alert! A chocy nut bar has been removed without payment!" +
" A chocy nut bar... has been REMOVED! WITHOUT PAYMENT! Alert, alert!",
getStackTraceTextArea(e));
//Display the window.
frame.pack();
frame.setLocation(SCREENCENTER.x - frame.getSize().width/2,
SCREENCENTER.y - frame.getSize().height/2);
frame.setVisible(true);
t.setModal(true);
t.pack();
t.setLocation(getPos(t, t.getOwner()));
t.setVisible(true);
}
}
protected static JComponent getStackTraceTextArea(Throwable exception) {
JTextArea textArea = new JTextArea();
textArea.setEditable(false);
textArea.setLineWrap(false);
textArea.append(getTraceMessage(exception));
textArea.setCaretPosition(0);
JScrollPane scroll = new JScrollPane(textArea);
scroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
scroll.setPreferredSize(new Dimension(50, 140));
return scroll;
}
private static final String getTraceMessage(Throwable exception) {
StringBuilder out = new StringBuilder((new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"))
.format(new Date())+": Unhandled Exception: \n"
+exception.toString()+"\n\nStack Trace:\n");
StackTraceElement[] stackTrace = exception.getStackTrace();
for (int i = 0; i < stackTrace.length; i++) {
String toAppend = stackTrace[i].toString();
if (i != stackTrace.length-1) toAppend += "\n";
out.append(toAppend);
}
return out.toString();
}
public static final JTextArea makeMultiLineLabel(boolean selectable) {
JTextArea area = new JTextArea();
area.setWrapStyleWord(true);
area.setLineWrap(true);
area.setFont(UIManager.getFont("Label.font"));
area.setEditable(false);
area.setCursor(null);
area.setOpaque(false);
area.setFocusable(selectable);
area.setAlignmentX(JTextComponent.LEFT_ALIGNMENT);
area.setMinimumSize(new Dimension(0,0));
return area;
}
private static Point getPos(JDialog d, Window w) {
return new Point(w.getX()+(w.getWidth ()-d.getWidth ())/2,
w.getY()+(w.getHeight()-d.getHeight())/2);
}
public static void main(String[] args) {
//Schedule a job for the event dispatch thread:
//creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
编辑 实现了一些建议的更改后,问题仍然存在:
最佳答案
您遇到的问题是 GridBagLayout
试图处理无法遵守组件的 preferredSize
的情况,它恢复使用组件minimumSize
而不是...
您可以使用 GridBagConstraints#weightx
属性强制组件始终填充其列宽...
c = new GridBagConstraints();
c.gridx = 1;
c.gridy = 0;
c.fill = GridBagConstraints.BOTH;
c.weighty = 1.0;
c.weightx = 1.0;
contentPanel.add(shortText, c);
c = new GridBagConstraints();
c.gridx = 1;
c.gridy = 1;
c.fill = GridBagConstraints.BOTH;
c.weighty = 1.0;
c.weightx = 1.0;
contentPanel.add(messageText, c);
这不会阻止它缩小,但会阻止它从一种尺寸“捕捉”到另一种尺寸。
尽量避免使用 setPreferredSize
,查看 Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing?更多细节。而是使用 JTextArea
的 rows
和 columns
属性...
shortText.setRows(2); // for example
就我个人而言,我也会将 JTextArea
包裹在 JScrollPane
中,这样,为每个元素留出足够的空间就变得不太重要了
反馈...
现在,这个问题脱离了上下文,但在我看来,您将付出很多努力却收效甚微。
例如,您可以使用 JOptionPane
并利用 Swing 的 HTML 呈现功能...
import java.awt.EventQueue;
import javax.swing.JOptionPane;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class OptionPaneTest {
public static void main(String[] args) {
new OptionPaneTest();
}
public OptionPaneTest() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
StringBuilder sb = new StringBuilder(128);
sb.append("<html><b><p align=center>You won't get away with this!</p></b><br>");
sb.append("Alert! Alert! A chocy nut bar has been removed without payment!");
sb.append("<br>A chocy nut bar... has been REMOVED! WITHOUT PAYMENT! Alert, alert!");
JOptionPane.showMessageDialog(null, sb.toString(), "Alert", JOptionPane.WARNING_MESSAGE);
}
});
}
}
还有...
我想你会发现使用...
frame.setLocationRelativeTo(null);
那么更容易,也更省时......
frame.setLocation(SCREENCENTER.x - frame.getSize().width / 2,
SCREENCENTER.y - frame.getSize().height / 2);
这也意味着您也可以使用 t.setLocationRelativeTo(frame)
...
哦,还有红矮星引用 +1 ;)
根据问题的更新更新
解决方案仍然(基本上)相同,使用JTextArea#setRows
和JTextArea#setColumns
...
你的代码...
我的代码...
JTextArea shortText = makeMultiLineLabel(true);
shortText.setBorder(BorderFactory.createEtchedBorder());
shortText.setFont(shortText.getFont().deriveFont(Font.BOLD));
// FontMetrics fm = shortText.getFontMetrics(
// shortText.getFont());
// shortText.setPreferredSize(new Dimension(
// Math.min(fm.stringWidth(shortMessage), 300),
// fm.getHeight()));
shortText.setRows(2);
shortText.setColumns(20);
shortText.setText(shortMessage);
JTextArea messageText = makeMultiLineLabel(true);
messageText.setBorder(BorderFactory.createEtchedBorder());
messageText.setFont(shortText.getFont().deriveFont(Font.PLAIN));
// fm = messageText.getFontMetrics(
// messageText.getFont());
// messageText.setPreferredSize(new Dimension(
// Math.min(fm.stringWidth(message), 300),
// fm.getHeight()));
messageText.setRows(4);
messageText.setColumns(20);
messageText.setText(message);
您可能还想看看 SwingX 的 JXErrorDialog
关于java - JTextArea 在调整对话框大小时突然调整大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18392862/
我有 0 小时、3 小时、12 小时、24 小时、48 小时的数据组……我想绘制这些数据的图表,以便保留时间的比例。 runs <- c(1:25) hours <- as.factor(c(0, 3
例如,如果我选择了时间:下午 3 点和小时数:5 小时,则得到 (8pm) 作为答案“ 最佳答案 let calendar = Calendar.current let date = calendar
我有一个包含两个日期时间字段的表单。用户输入日期 (yyyy-mm-dd) 和时间(3 个框;小时、分钟、上午/下午)。 出于某种原因,第一个没有保存为 24 小时制。 以下数据为输入结果: 2011
我一直在尝试使用导出单位进行计算,但到目前为止我还没有取得任何成果。 我已经尝试过mathjs ,但如果我输入 1 小时 * 1 英里/小时,我会得到 UnsupportedTypeError: Fu
我有两组要运行的 cronjob。第一个应该每 3 小时运行一次,第二个也应该每 3 小时运行一次,但比第一组晚一个小时。什么是正确的语法? // every 3 hours 17 */3 * *
我知道 AWS 中的预留实例更多的是计费而不是实际实例——它们没有附加到实际实例——我想知道: 如果我在特定区域和可用区中购买特定时间的预留实例 - 如果我每天 24 小时使用单个实例与运行 24 个
我试过: seq( from=as.POSIXct("2012-1-1 0", tz="UTC"), to=as.POSIXct("2012-1-3 23", tz="UTC"),
我有一个带有“日期”列的表。我想按小时分组指定日期。 最佳答案 Select TO_CHAR(date,'HH24') from table where date = TO_DATE('2011022
我知道如何在 SQL (SQL Server) 中获取当前日期,但要获取当天的开始时间: select dateadd(DAY, datediff(day, 0, getdate()),0) (res
我正在尝试在游戏之间创建一个计时器,以便用户在失去生命后必须等待 5 分钟才能再次玩游戏。但是我不确定最好的方法是什么。 我还需要它来防止用户在“设置”中编辑他们的时间。 实现这一目标的最佳方法是什么
我的查询有误。该错误显示预期的已知函数,得到“HOUR”。如果我删除这部分,查询将正常工作 (AND HOUR({$nowDate}) = 11) SELECT c FROM ProConvocati
var d1 = new Date(); var d2 = new Date(); d2.setHours(d1.getHours() +01); alert(d2); 这部分没问题。现在我试图在 (
我正在构建一个用于练习的基本时钟应用程序,但出于某种原因,时间不会自动更改为最新的分钟或小时。例如,当前时间是 17:56,但它显示的是 17:54,这是我打开应用程序的最后时间。 NSDate *n
我创建了一张图片,我想将其用作页面的 hr。当它被上传时,它一直向左对齐。我希望它居中,在标题下。这是我的 CSS 代码: .section-underline { height: 35px
这个问题已经有答案了: Getting difference in seconds from two dates in JavaScript (2 个回答) 已关闭 4 年前。 我想计算两个具有不同格
我需要计算到某个日期/时间的剩余时间(天/小时)。 但是,我没有使用静态日期。 假设我在 每个星期日 的 17:00 有一个事件。我需要显示到下一个事件的剩余时间,即即将到来的星期日 17:00。 我
我正在执行这个脚本: SELECT EXTRACT(HOUR FROM TIMEDIFF('2009-12-12 13:13:13', NOW())); 我得到:-838。这是提取时 MySQL 可以
复制代码 代码如下: /** * 小时:分钟的正则表达式检查<br> * <br> * @param pInput 要检查的字符串 * @return boolean 返
连wifi5元/小时 独领风骚 朕好帅 今晚你是我的人 十里桃花 高端定制厕所VP专用 一只老母猪 在家好无聊 你爹的wifi 密码是叫爸爸全拼 关晓彤和鹿晗分手了吗 蹭了我的
我有以下数据框列: 我需要将 csv 列中的对象字符串数据转换为总秒数。 示例:10m -> 600s 我试过这段代码: df.duration = str(datetime.timedelta(df
我是一名优秀的程序员,十分优秀!