提供了 OutputStream 的输出显示控件(整理修改版)

博客介绍了对原有OutputStream输出显示控件的修改,解决了不换行时不提交更改的问题。采用了类似JViewPort的响应机制,利用内部timer控制更新,并强调所有OutputStream的输出操作必须在EDT中执行。

之前发的小控件有点问题,不换行就不会提交更改,修改代码如下:


import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

public class JOutputPane extends JTextArea {
  
  private OutputStream out = this.new PaneOutputStream();
  
  private Color candy = new Color(240, 240, 255);
  
  @Override
  public boolean isOpaque() {
    
    return false;
  }
  
  public OutputStream getOutputStream() {
    
    return out;
  }

  @Override
  protected void paintComponent(Graphics g) {

    int width = getWidth();
    int height = getHeight();

    Color old = g.getColor();
    g.setColor(getBackground());
    g.fillRect(0, 0, width, height);

    Rectangle r = new Rectangle();
    r.x = 0;
    r.y = 0;
    r.width = width;
    r.height = getRowHeight();

    g.setColor(candy);
    for (int heightIncrement = 2 * getRowHeight();
            r.y < height;
            r.y += heightIncrement) {

      g.fillRect(r.x, r.y, r.width, r.height);
    }
    g.setColor(old);

    super.paintComponent(g);
  }
  
  private class PaneOutputStream extends OutputStream {
    
    private final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
    private final Timer timer;
    
    private PaneOutputStream() {
      
      timer = new Timer(50, new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
          
          commit();
        }
      });
    }
    
    @Override
    public void write(int b) throws IOException {
      
      buffer.write(b);
      timer.restart();
    }
    
    private void commit() {
      
      assert SwingUtilities.isEventDispatchThread();
      
      timer.stop();
      if( buffer.size() > 0 ) {
        
        append(buffer.toString());
        buffer.reset();
      }
    }
  }
}

设计上模仿了 JViewPort 对频繁的 scroll 动作的响应方式,用了一个内部的 timer 来控制更新。

需要特别说明的是,对返回的 OutputStream 的任何输出都应该在 EDT 内进行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值