実現したいこと
とある印刷プレビュー画面にSwingのJEditorPaneを使って文字修飾を表現する為のパネルを作成しています。その画面には画面全体をズームする機能があります。これを文字列の表示位置をずらさずに表示できるようにしたいです。
発生している問題・分からないこと
とある印刷プレビュー画面にSwingのJEditorPaneを使って文字修飾を表現する為のパネルを作成しています。その画面には画面全体をズームする機能があります。
試しにテスト用の画面を作成し、試しているのですがズームを拡大したり縮小すると文字の配置がおかしくなり、文字列毎(HTMLタグ毎)にスペースがあいたり重なったりしてしまいます。
■拡大縮小しない場合
■3倍に拡大した場合
これをズームを拡大・縮小しても表示位置がおかしくならないようにしたいのですが、どのように実装すればいいでしょうか。
該当のソースコード
Swing
1import java.awt.Font; 2import java.awt.Graphics; 3import java.awt.Graphics2D; 4import java.awt.Rectangle; 5import java.awt.Shape; 6import java.awt.geom.AffineTransform; 7 8import javax.swing.JFrame; 9import javax.swing.JScrollPane; 10import javax.swing.JTextPane; 11import javax.swing.text.AbstractDocument; 12import javax.swing.text.AttributeSet; 13import javax.swing.text.BadLocationException; 14import javax.swing.text.Element; 15import javax.swing.text.FlowView; 16import javax.swing.text.ParagraphView; 17import javax.swing.text.Position; 18import javax.swing.text.StyleConstants; 19import javax.swing.text.View; 20import javax.swing.text.ViewFactory; 21import javax.swing.text.html.BlockView; 22import javax.swing.text.html.CSS; 23import javax.swing.text.html.HTML; 24import javax.swing.text.html.HTMLDocument; 25import javax.swing.text.html.HTMLEditorKit; 26 27public class ScaleHTMLEditorTest { 28 29 30 private static final long serialVersionUID = 1L; 31 32 public static void main(String[] args) { 33 JFrame frame = new JFrame(); 34 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 35 // Create a new JEditorPane 36 JTextPane yourPane = new JTextPane(); 37 yourPane.setContentType( "text/html"); 38 String htmlText ="<html style='size: 120%'><body style='font-size:1px;'><font size='4' color='#ff0000'>おおおおお<span style='font-weight:bold;font-style:italic;text-decoration:underline;'>おおああaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</span></i></b></font><font size='2'>aaa</font>" 39 + "<font size='2'>ててて</font><font size='1'>うううううeeeeeeeeeeeee</font><div/></body></html>"; 40 // Set the custom HTMLEditorKit 41 // Set the zoom to 150% 42 yourPane.setFont(new Font("MS ゴシック", Font.PLAIN, 12)); 43 HTMLDocument doc = (HTMLDocument) yourPane.getEditorKit().createDefaultDocument(); 44 yourPane.setEditorKit(new LargeHTMLEditorKit()); 45 yourPane.getDocument().putProperty("ZOOM_FACTOR", 46 new Double(3)); 47// doc.setCharacterAttributes(0, 1, attrs, true); 48 yourPane.setText(htmlText); 49 JScrollPane scroll = new JScrollPane(yourPane); 50 frame.getContentPane().add(scroll); 51 52 frame.setSize(1000, 500); 53 frame.setVisible(true); 54 } 55 56 public static class LargeHTMLEditorKit extends HTMLEditorKit { 57 58 /** 59 * 60 */ 61 private static final long serialVersionUID = 1L; 62 ViewFactory factory = new MyViewFactory(); 63 64 @Override 65 public ViewFactory getViewFactory() { 66 return factory; 67 } 68 69 class MyViewFactory extends HTMLFactory { 70 @Override 71 public View create(Element elem) { 72 AttributeSet attrs = elem.getAttributes(); 73 Object elementName = attrs.getAttribute(AbstractDocument.ElementNameAttribute); 74 Object o = (elementName != null) ? null : attrs.getAttribute(StyleConstants.NameAttribute); 75 if (o instanceof HTML.Tag) { 76 HTML.Tag kind = (HTML.Tag) o; 77 if (kind == HTML.Tag.HTML) { 78 return new HTMLBlockView(elem); 79 } else if (kind == HTML.Tag.IMPLIED) { 80 String ws = (String) elem.getAttributes().getAttribute(CSS.Attribute.WHITE_SPACE); 81 if ((ws != null) && ws.equals("pre")) { 82 return super.create(elem); 83 } 84 return new HTMLParagraphView(elem); 85 } else if ((kind == HTML.Tag.P) || 86 (kind == HTML.Tag.H1) || 87 (kind == HTML.Tag.H2) || 88 (kind == HTML.Tag.H3) || 89 (kind == HTML.Tag.H4) || 90 (kind == HTML.Tag.H5) || 91 (kind == HTML.Tag.H6) || 92 (kind == HTML.Tag.DT)) { 93 // paragraph 94 return new HTMLParagraphView(elem); 95 96 } 97 98 } 99 return super.create(elem); 100 } 101 102 } 103 104 private class HTMLBlockView extends BlockView { 105 106 public HTMLBlockView(Element elem) { 107 super(elem, View.Y_AXIS); 108 } 109 110 @Override 111 protected void layout(int width, int height) { 112 if (width < Integer.MAX_VALUE) { 113 super.layout(new Double(width / getZoomFactor()).intValue(), 114 new Double(height * 115 getZoomFactor()).intValue()); 116 } 117 } 118 119 public double getZoomFactor() { 120 Double scale = (Double) getDocument().getProperty("ZOOM_FACTOR"); 121 if (scale != null) { 122 return scale.doubleValue(); 123 } 124 125 return 1; 126 } 127 128 @Override 129 public void paint(Graphics g, Shape allocation) { 130 Graphics2D g2d = (Graphics2D) g; 131 double zoomFactor = getZoomFactor(); 132 AffineTransform old = g2d.getTransform(); 133// g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON); 134 g2d.scale(zoomFactor, zoomFactor); 135 136 super.paint(g2d, allocation); 137 g2d.setTransform(old); 138 } 139 140 @Override 141 public float getMinimumSpan(int axis) { 142 float f = super.getMinimumSpan(axis); 143 f *= getZoomFactor(); 144 return f; 145 } 146 147 @Override 148 public float getMaximumSpan(int axis) { 149 float f = super.getMaximumSpan(axis); 150 f *= getZoomFactor(); 151 return f; 152 } 153 154 @Override 155 public float getPreferredSpan(int axis) { 156 float f = super.getPreferredSpan(axis); 157 f *= getZoomFactor(); 158 return f; 159 } 160 161 @Override 162 public Shape modelToView(int pos, Shape a, Position.Bias b) throws BadLocationException { 163 double zoomFactor = getZoomFactor(); 164 Rectangle alloc; 165 alloc = a.getBounds(); 166 Shape s = super.modelToView(pos, alloc, b); 167 alloc = s.getBounds(); 168 alloc.x *= zoomFactor; 169 alloc.y *= zoomFactor; 170 alloc.width *= zoomFactor; 171 alloc.height *= zoomFactor; 172 173 return alloc; 174 } 175 176 @Override 177 public int viewToModel(float x, float y, Shape a, 178 Position.Bias[] bias) { 179 double zoomFactor = getZoomFactor(); 180 Rectangle alloc = a.getBounds(); 181 x /= zoomFactor; 182 y /= zoomFactor; 183 alloc.x /= zoomFactor; 184 alloc.y /= zoomFactor; 185 alloc.width /= zoomFactor; 186 alloc.height /= zoomFactor; 187 188 return super.viewToModel(x, y, alloc, bias); 189 } 190 191 } 192 193 class HTMLParagraphView extends ParagraphView { 194 195 public int MAX_VIEW_SIZE = 100; 196 197 public HTMLParagraphView(Element elem) { 198 super(elem); 199 strategy = new HTMLParagraphView.HTMLFlowStrategy(); 200 } 201 202 public class HTMLFlowStrategy extends FlowStrategy { 203 @Override 204 protected View createView(FlowView fv, int startOffset, int spanLeft, int rowIndex) { 205 View res = super.createView(fv, startOffset, spanLeft, rowIndex); 206 if (res.getEndOffset() - res.getStartOffset() > MAX_VIEW_SIZE) { 207 res = res.createFragment(startOffset, startOffset + MAX_VIEW_SIZE); 208 } 209 return res; 210 } 211 212 } 213 214 @Override 215 public int getResizeWeight(int axis) { 216 return 0; 217 } 218 } 219 } 220 221} 222
試したこと・調べたこと
上記の詳細・結果
下記のURLの部分に記載しているコードを試しているのですが、うまくいかなかったです。
https://stackoverflow.com/questions/680817/is-it-possible-to-zoom-scale-font-size-and-image-size-in-jeditorpane
補足
特になし
0 コメント