简体   繁体   English

JTextArea在java swing中的边框

[英]JTextArea border in java swing

I am new to java and creating UI widgets using java and created the following class for the same. 我是java新手并使用java创建UI小部件并为此创建了以下类。 But in order to add border to textarea I know that I have to use borderfactory class. 但是为了向textarea添加边框,我知道我必须使用borderfactory类。 But as I have separate class for JFrame and JTextArea I could not do it. 但是因为我有JFrame和JTextArea的单独类,所以我无法做到。 Any help? 有帮助吗?

class

import javax.swing.*;
import java.awt.*;
import javax.swing.BorderFactory;

    public class UIFactory {

        //Border border = BorderFactory.createLineBorder(Color.BLACK);
        public JButton newButton(int posx, int posy, int buttonWidth, int buttonHeight) {
            JButton b = new JButton("Test");
            b.setBounds(posx, posy, buttonWidth, buttonHeight);
            return b;
        }

        public JFrame newFrame(int width, int height) {
            JFrame f = new JFrame();
            f.setSize(width, height);
            f.setLayout(null);
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            return f;
        }

        public JTextArea newTextArea(int xpos, int ypos, int twidth, int theight) {
            JTextArea t = new JTextArea(300,300);
            JScrollPane sp = new JScrollPane(t);            
            t.setBounds(xpos, ypos, twidth, theight);
            t.setBackground(Color.orange);  
            t.setForeground(Color.black); 
         //   t.setBorder(BorderFactory.createCompoundBorder(border,BorderFactory.createEmptyBorder(10, 10, 10, 10)));            
            return t;
        }

}

and my main program 和我的主要计划

import javax.swing.*;
import java.awt.*;
public class MyUI {
public static void main(String[] args) {
        UIFactory ui = new UIFactory();    
        JFrame mainf = ui.newFrame(800, 800);        
        mainf.setLocation(400, 400);

        JButton b2;
        JButton b3;


        mainf.add(b2 = ui.newButton(50, 50, 100, 50));
        mainf.add(b3 = ui.newButton(50, 100, 100, 50));   

        JTextArea area;
        mainf.add(area = ui.newTextArea(170,50,1600,300));
        mainf.setVisible(true);
        mainf.add(area = ui.newTextArea(170,400,1600,300));
        mainf.setVisible(true);
    }
}

try below in newTextArea 在newTextArea中尝试以下

Border border = BorderFactory.createLineBorder(Color.BLACK);
    t.setBorder(BorderFactory.createCompoundBorder(border,
            BorderFactory.createEmptyBorder(10, 10, 10, 10)));

There are a couple of ways you might be able to achieve this, you could just apply the border AFTER the fact to either the frame or the JTextArea or you could supply the Border value to either methods based on your needs 有几种方法可以实现这一点,你可以将事后的边框应用到框架或JTextArea或者你可以根据你的需要为这两种方法提供Border

My preference would be to consider using a builder pattern, which would allow you to supply the properties your interested in and make the final result. 我倾向于考虑使用构建器模式,这将允许您提供您感兴趣的属性并生成最终结果。

Because many of the properties are shared between components, I'd be tempted to start with an abstract implementation 因为许多属性是在组件之间共享的,所以我很想从一个抽象的实现开始

public abstract class ComponentBuilder<B extends ComponentBuilder<B, T>, T extends JComponent> {

    public static final String BORDER = "border";
    public static final String FOREGROUND = "foreground";
    public static final String BACKGROUND = "background";

    private Map<String, Object> properties = new HashMap<>();

    protected abstract B self();

    protected void put(String key, Object value) {
        properties.put(key, value);
    }

    public B withBorder(Border border) {
        put(BORDER, border);
        return self();
    }

    public B withForeground(Color color) {
        put(FOREGROUND, color);
        return self();
    }

    public B withBackground(Color color) {
        put(BACKGROUND, color);
        return self();
    }

    public abstract T build();

    public <O> O get(String key, Class<O> type, O defaultValue) {
        Object value = properties.get(key);
        if (value == null) {
            return defaultValue;
        } else if (value.getClass().isAssignableFrom(type)) {
            return (O)value;
        }
        return defaultValue;
    }

    protected Border getBorder() {
        return get(BORDER, Border.class, null);
    }

    protected int getInt(String key, int defaultValue) {
        return get(key, int.class, defaultValue);
    }

    protected Color getColor(String key, Color defaultValue) {
        return get(key, Color.class, defaultValue);
    }

    protected Color getForeground() {
        return getColor(FOREGROUND, null);
    }

    protected Color getBackground() {
        return getColor(BACKGROUND, null);
    }
}

Okay, don't panic, that's some awesome generic trickery, but trust me, it makes the whole API very flexible 好吧,不要惊慌,这是一些很棒的通用技巧,但相信我,它使整个API非常灵活

Now, you could include a lot more properties, like font for example, but let's stick with a basic example. 现在,您可以包含更多属性,例如字体,但让我们坚持使用一个基本示例。

Next, we need a text area builder to build a textarea the way we want it 接下来,我们需要一个文本区域构建器来按照我们想要的方式构建textarea

public class TextAreaBuilder extends ComponentBuilder<TextAreaBuilder, JTextArea> {

    public static final String ROWS = "rows";
    public static final String COLUMNS = "columns";

    @Override
    protected TextAreaBuilder self() {
        return this;
    }

    public TextAreaBuilder withRows(int rows) {
        put(ROWS, rows);
        return self();
    }

    public TextAreaBuilder withColumns(int cols) {
        put(COLUMNS, cols);
        return self();
    }

    protected int getRows(int defaultValue) {
        return getInt(ROWS, defaultValue);
    }

    protected int getColumns(int defaultValue) {
        return getInt(COLUMNS, defaultValue);
    }

    @Override
    public JTextArea build() {
        JTextArea ta = new JTextArea();
        ta.setColumns(getColumns(0));
        ta.setRows(getRows(0));
        ta.setBorder(getBorder());
        ta.setForeground(getForeground());
        ta.setBackground(getBackground());
        return ta;
    }

}

Then we can simply make a new JTextArea with the properties we want to use... 然后我们可以简单地使用我们想要使用的属性创建一个新的JTextArea ...

JTextArea ta = new TextAreaBuilder().
        withColumns(40).
        withRows(20).
        withBackground(Color.ORANGE).
        withForeground(Color.BLACK).
        withBorder(BorderFactory.createLineBorder(Color.RED)).
        build();

Done! 完成!

Now, if all that seems "to hard", you could simply change your current method to require an instance of Border , for example 现在,如果所有看起来“变得困难”,您可以简单地将当前方法更改为需要Border的实例

public JTextArea newTextArea(int rows, int cols, Border border) {
    JTextArea ta = new JTextArea(rows, cols);
    ta.setBorder(border);
    return ta;
}

Avoid using null layouts, pixel perfect layouts are an illusion within modern ui design. 避免使用null布局,像素完美布局是现代ui设计中的错觉。 There are too many factors which affect the individual size of components, none of which you can control. 影响组件个体大小的因素太多,您无法控制。 Swing was designed to work with layout managers at the core, discarding these will lead to no end of issues and problems that you will spend more and more time trying to rectify Swing旨在与布局管理器一起工作,放弃这些将导致问题和问题的结束,您将花费越来越多的时间来纠正

Have a look at Why is it frowned upon to use a null layout in SWING? 看看为什么在SWING中使用空布局不赞成? and Laying Out Components Within a Container for more details 在容器中布置组件以获取更多详细信息

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM