概括问题:我想允许用户放大或缩小不可编辑的JTextPane。运行在前面的问题中提交的示例程序,该程序只是缩放了Graphics对象,导致运行的粗体和非粗体之间的间距不一致。
下面的示例程序尝试通过将文本窗格绘制为100%的BufferedImage并缩放图像来解决该问题。这解决了间距不一致的问题,但是生成的文本缺乏清晰度。是否存在渲染提示(或其他更改)的某种组合,这些组合会产生清晰的文本?
在此先感谢您对此方法的可行性提出任何建议或意见。
import java.awt.BorderLayout; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.RenderingHints; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.image.BufferedImage; import javax.swing.Box; import javax.swing.JComboBox; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JTextPane; import javax.swing.SwingUtilities; import javax.swing.text.BadLocationException; import javax.swing.text.Style; import javax.swing.text.StyleConstants; import javax.swing.text.StyleContext; import javax.swing.text.StyledDocument; public class ScaledJTextPane extends JTextPane { double scale_; BufferedImage raster_; public ScaledJTextPane() { scale_ = 1.0; raster_ = null; } public void draw(Graphics g) { if (raster_ == null) { // Draw this text pane to a BufferedImage at 100% raster_ = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB); Graphics2D g2 = raster_.createGraphics(); g2.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_OFF); paint(g2); } Graphics2D g2 = (Graphics2D) g; // Experiment with different rendering hints g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON); g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); // Scale the BufferedImage g2.scale(scale_, scale_); g2.drawImage(raster_, 0, 0, null); } public void setScale(double scale) { scale_ = scale; raster_ = null; } private static void createAndShowGUI() { // Create and set up the window. JFrame frame = new JFrame("ScaledJTextPane using BufferedImage"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); final ScaledJTextPane scaledTextPane = new ScaledJTextPane(); StyledDocument doc = scaledTextPane.getStyledDocument(); Style defaultStyle = StyleContext.getDefaultStyleContext().getStyle(StyleContext.DEFAULT_STYLE); Style boldStyle = doc.addStyle("bold", defaultStyle); StyleConstants.setBold(boldStyle, true); scaledTextPane.setFont(new Font("Dialog", Font.PLAIN, 14)); String boldText = "Four score and seven years ago "; String plainText = "our fathers brought forth on this continent, a new nation, conceived in Liberty, and dedicated to the proposition that all men are created equal."; try { doc.insertString(doc.getLength(), boldText, boldStyle); doc.insertString(doc.getLength(), plainText, defaultStyle); } catch (BadLocationException ble) { System.err.println("Couldn't insert text into text pane."); } final JComboBox zoomCombo=new JComboBox(new String[] {"75%", "100%", "150%", "175%", "200%"}); final JPanel panel = new JPanel() { protected void paintComponent(Graphics g) { super.paintComponent(g); scaledTextPane.draw(g); } }; zoomCombo.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { String s = (String) zoomCombo.getSelectedItem(); s = s.substring(0, s.length() - 1); double scale = new Double(s).doubleValue() / 100; scaledTextPane.setScale(scale); panel.invalidate(); panel.repaint(); } }); zoomCombo.setSelectedItem("100%"); JPanel optionsPanel = new JPanel(new GridBagLayout()); GridBagConstraints c = new GridBagConstraints(); c.gridx = 0; c.gridy = 0; c.anchor = GridBagConstraints.WEST; optionsPanel.add(zoomCombo, c); c.gridx++; c.weightx = 1; c.fill = GridBagConstraints.HORIZONTAL; optionsPanel.add(Box.createHorizontalGlue(), c); // Add content to the window. scaledTextPane.setBounds(0, 0, 450, 300); panel.setOpaque(true); panel.setBackground(Color.WHITE); frame.getContentPane().add(panel, BorderLayout.CENTER); frame.getContentPane().add(optionsPanel, BorderLayout.NORTH); frame.setSize(900, 300); //Display the window. frame.setVisible(true); } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { createAndShowGUI(); } }); } }
也许http://java-sl.com/Scale_In_JEditorPane.html可以帮助您。