Java Swing:JTextArea文本缩放非修改字体大小实现方案
Java Swing 文本编辑器无字体修改的缩放实现
不直接修改JTextArea字体大小实现缩放的核心逻辑是将缩放逻辑放在视图渲染层,通过仿射变换干预组件的绘制过程,全程不改动组件绑定的原始字体属性,也不会影响文本内容的存储配置。
实现思路
- 为编辑区维护独立的缩放比例变量,默认值
1.0对应100%原始大小,设置缩放上下限(如最小0.5倍、最大3.0倍)避免显示异常 - 自定义
JTextArea子类,重写绘制方法,在执行默认绘制逻辑前给绘图上下文添加缩放变换 - 同步重写组件首选尺寸计算逻辑,按缩放比例调整返回值,保证滚动条、布局适配正常
- 缩放按钮触发时只修改缩放比例值,触发组件重绘、重新布局即可完成缩放
完整可运行代码
package zoomtest; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JTextArea; import javax.swing.JScrollPane; // 自定义支持视图缩放的文本区,不修改原始字体 class ScaledTextArea extends JTextArea { // 缩放比例,默认1.0即原始大小 private double scale = 1.0; // 缩放步长 private static final double SCALE_STEP = 0.1; // 缩放上下限 private static final double MIN_SCALE = 0.5; private static final double MAX_SCALE = 3.0; public void zoomIn() { if (scale < MAX_SCALE) { scale += SCALE_STEP; revalidate(); repaint(); } } public void zoomOut() { if (scale > MIN_SCALE) { scale -= SCALE_STEP; revalidate(); repaint(); } } public double getScale() { return scale; } @Override protected void paintComponent(Graphics g) { // 创建绘图上下文副本,避免影响全局绘制配置 Graphics2D g2d = (Graphics2D) g.create(); // 应用缩放变换 g2d.scale(scale, scale); // 调用父类原始绘制逻辑 super.paintComponent(g2d); g2d.dispose(); } @Override public Dimension getPreferredSize() { // 按缩放比例调整首选尺寸,适配滚动条 Dimension baseSize = super.getPreferredSize(); return new Dimension( (int) (baseSize.width * scale), (int) (baseSize.height * scale) ); } // 如果需要缩放后鼠标选中文本位置完全精准,可取消注释以下两个坐标转换方法 /* @Override public Rectangle modelToView(int pos) throws BadLocationException { Rectangle rect = super.modelToView(pos); rect.x *= scale; rect.y *= scale; rect.width *= scale; rect.height *= scale; return rect; } @Override public int viewToModel(Point pt) { Point scaledPt = new Point((int)(pt.x / scale), (int)(pt.y / scale)); return super.viewToModel(scaledPt); } */ } public class zoom { private JFrame frame; public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { public void run() { try { zoom window = new zoom(); window.frame.setVisible(true); } catch (Exception e) { e.printStackTrace(); } } }); } public zoom() { initialize(); } private void initialize() { frame = new JFrame(); frame.setBounds(100, 100, 450, 300); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JPanel panel = new JPanel(); frame.getContentPane().add(panel, BorderLayout.NORTH); ScaledTextArea jta = new ScaledTextArea(); // 给文本区加滚动面板,缩放后可滚动查看内容 JScrollPane scrollPane = new JScrollPane(jta); frame.getContentPane().add(scrollPane, BorderLayout.CENTER); JButton ZoomIn = new JButton("Zoom in"); ZoomIn.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { jta.zoomIn(); } }); panel.add(ZoomIn); JButton Zoomout = new JButton("Zoom out"); Zoomout.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { jta.zoomOut(); } }); panel.add(Zoomout); } }
补充说明
- 这个实现全程没有修改
JTextArea的Font属性,调用jta.getFont()获取到的始终是初始配置的字体值,和缩放状态无关 - 代码默认给文本区包裹了
JScrollPane,大缩放比例下可以通过滚动条查看全部内容 - 注释中给出的坐标转换重写逻辑按需开启即可,开启后缩放状态下鼠标点击定位、文本选中的位置会完全精准,没有偏移
- 如果需要支持Ctrl+滚轮缩放,只需要给文本区添加鼠标滚轮监听器,判断Ctrl键按下时调用对应的
zoomIn()/zoomOut()方法即可,逻辑和按钮触发完全一致
内容的提问来源于stack exchange,提问作者user18466361
相关产品推荐
相关产品推荐

