Java SWT/WindowBuilder中的多行按钮文本?

Java SWT/WindowBuilder中的多行按钮文本?,java,eclipse,swt,windowbuilder,Java,Eclipse,Swt,Windowbuilder,有没有办法强制SWT按钮文本跨越两行,可以在SWT代码中手动执行,也可以使用WindowBuilder GUI执行? 我有这个: 我想要这样的东西(通过数字改变图像来实现): 可能吗?如何设置?我会尝试将按钮文本设置为一个带有“\n”字符的字符串,您希望在该字符串中出现换行。我能想到的唯一方法是通过JNI/JNA。请注意,如果沿着这条路走下去,您将通过调用特定于平台的本机函数来打破Java的平台独立性 对于Windows,请查看。假设您的代码类似于: Button btn = new But

有没有办法强制SWT按钮文本跨越两行,可以在SWT代码中手动执行,也可以使用WindowBuilder GUI执行? 我有这个:

我想要这样的东西(通过数字改变图像来实现):


可能吗?如何设置?

我会尝试将按钮文本设置为一个带有“\n”字符的字符串,您希望在该字符串中出现换行。

我能想到的唯一方法是通过JNI/JNA。请注意,如果沿着这条路走下去,您将通过调用特定于平台的本机函数来打破Java的平台独立性

对于Windows,请查看。假设您的代码类似于:

Button btn = new Button(shell, SWT.PUSH);
btn.setText("Hello world!");
您可以通过
btn.handle
获取句柄。有了一点JNA魔法,沿着这些路线可能会有一些事情:

final User32 lib = (User32) Native.loadLibrary("user32", User32.class);
final HWND hWnd = new W32API.HWND(new W32API.UINT_PTR(btn.handle)
        .toPointer());
final String text = "Hello\nworld!"; // or "Hello\r\nworld!"?
lib.SetWindowText(hWnd, text.toCharArray());

我实际上无法让它工作(它在
SetWindowText()
上给出了一个
java.lang.UnsatifiedLinkError
,我无法整理),但这可能会为您指明正确的方向。

我会创建一个自定义控件,而不是深入研究本机代码。扩展组合,为多行文字使用标签,并在二维图形中添加一些装饰。在图形环境中,有用于圆形矩形和渐变绘制的方法。它可能看起来不像一个本地小部件,但在我看来,它比使用JNI要好。

实际上在swing中有一种非常简单的方法,而不是在SWT中。当我第一次发布这个答案时,我误读了这个问题,但是由于我在寻找swing解决方案时找到了自己的方法,我将把它留给其他人

button.setText("<html>My<br>Text<br>");
button.setText(“我的
文本
”);
许多swing组件呈现HTML


在查看发布日期时,我不确定这是否是对一个那么老的问题的相关答案,但我在试图解决这个问题时发现了这个问题,所以我想与大家分享。干杯。

以下代码实现了此功能:

final int style = OS.GetWindowLong(button.handle, OS.GWL_STYLE);
OS.SetWindowLong(button.handle, OS.GWL_STYLE, style | OS.BS_MULTILINE);
button.setText("line 1\nline 2");
您只需导入org.eclipse.swt.internal.win32.OS即可。当然,该类和按钮内的handle字段不是SWTAPI的一部分,因此您的代码不再是可移植的。但是这些函数是在windowsapi中定义的,所以您不必太担心它们在SWT的未来版本中会发生什么变化

请注意,在进行此更改后,computeSize()不再正常工作


编辑:我负责computeSize()和GWL样式的完整类

import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.internal.win32.OS;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;


public class MultilineButton extends Button {

    public MultilineButton(Composite parent, int style) {
        super(parent, style);
        final int gwlStyle = OS.GetWindowLong(this.handle, OS.GWL_STYLE);
        OS.SetWindowLong(this.handle, OS.GWL_STYLE, gwlStyle | OS.BS_MULTILINE);
    }

    @Override
    protected void checkSubclass() {
    }

    @Override
    public Point computeSize(int wHint, int hHint, boolean changed) {
        final Point size = super.computeSize(wHint, hHint, changed);
        final GC gc = new GC(this);

        final String multiLineText = this.getText();
        final Point multiLineTextSize = gc.textExtent(multiLineText, SWT.DRAW_DELIMITER);

        final String flatText = multiLineText.replace('\n', ' ');
        final Point flatTextSize = gc.textExtent(flatText);

        gc.dispose();

        size.x -= flatTextSize.x - multiLineTextSize.x;
        size.y += multiLineTextSize.y - flatTextSize.y;

        return size;
    }
}

通过添加SWT.WRAP作为按钮的样式,并在文本中插入“\n”设置为按钮标签,我能够使多行按钮文本正常工作

....
Button check = new Button(composite, SWT.WRAP | SWT.PUSH );
check.setText("Multi\n Line\n Button \n Text");
....
即使button.setText(..)java文档说按钮标签不能包含新行字符,但当SWT.WRAP作为样式添加时,它仍然有效(“\n”在未设置SWT.WRAP时被忽略)

我只是觉得这可能有用


试着用图像设置它,尽管不建议Monikka通过传递
SWT来回答下面的问题。包装
按钮样式为我解决了这个问题。e、 g.
新建按钮(父级,SWT.WRAP | SWT.PUSH)
仔细阅读javadoc中的SWT按钮小部件。对于
setText()
可以清楚地看到:
此方法设置按钮标签。标签可能包含助记字符,但不得包含行分隔符。
以上注释正确。目前看来,在SWT中以本机方式执行此操作是不可能的。选项是使用图像或使用非本机控件。例如,可以在SWT控件之间嵌入Swing控件。当然,我会非常慎重地考虑这是否值得。在这个项目中,对我来说,要完成这项任务并不是世界末日,要知道完成这项任务所涉及的缺陷,我将避免尝试。谢谢你的信息!我想我在这方面做得有点过火了。在我看来,这种方法是使用纯SWT的唯一方法。这是行不通的。SWT已使用此函数
SetWindowText()
。Windows删除第一个NL之后的所有字符,而不是SWT。也就是说,除非您设置了
ES\u多行
样式标志。关于完整的Java代码,请参见我的答案。请注意,问题是关于SWT的,而不是Swing.Ah。我错过了。抱歉。我仅将其作为行分隔符\n实现。如果要使用\r\n,请更新代码以在computeSize中将其转换为single。这比我使用GWL\U样式的解决方案要好。但是您仍然需要覆盖computeSize()。我更新了代码以使用SWT.WRAP。