Я работаю над Markdown Editorkit (от javax.swing.text ).
Сигсерчик, кажется, работает нормально, но теперь мне нужно сделать ViewFactory .
Тестовая строка анализируется таким образом, что мы получаем следующую структуру:
Проанализируется, что мы получаем следующую структуру:
.root
| - paragraph
| | - text
| - list
| | - paragraph
| | | - text
| | | - code span
| | | - text
Paragraph is converted to the BoxView(elem, X_AXIS), it works great.
Text is converted to my custom View, which is also OK.
List is converted to my custom CompositeView, which is the main problem, as components on it just do not show up (at все). < /p>
У меня есть следующие классы: < /p>
class MDListView extends MarkdownContainerView{
public MDListView(MDList e,ViewFactory f){
super(e);
}
public float getPreferredSpan(int axis){
//Returns a correct non-empty rectangle.
}
public Shape getChildAllocation(int index,Shape s){
Rectangle r=s.getBounds();
return new Rectangle(r.x,r.y+(int)(index*getPreferredSpan(Y_AXIS)/getViewCount()),r.width,r.height/getViewCount());
}
public void replace(int offset,int length,View[]views){
super.replace(offset,length,views);
//Some additional logic
}
protected void childAllocation(int index,Rectangle a){
a.setBounds(getChildAllocation(index,a).getBounds());
}
}
< /code>
и < /p>
static abstract class MarkdownContainerView extends CompositeView{
public MarkdownContainerView(Element e){
super(e);
}
public void paint(Graphics g,Shape allocation){
for(int i=0;i < /strong> соответственно. < /p>
getview(0).childallocation - это пустое < /strong> прямоугольник. < /p>
getChildAllocation никогда не называется [/b].
еще больше кода
Вся реализация ViewFactory представлена ниже, в случае, если он используется.package com.myenvironment.swing.markdown;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Shape;
import javax.swing.text.BadLocationException;
import javax.swing.text.BoxView;
import javax.swing.text.CompositeView;
import javax.swing.text.Element;
import javax.swing.text.Position.Bias;
import javax.swing.text.View;
import javax.swing.text.ViewFactory;
import com.myenvironment.swing.markdown.MarkdownDocument.CodeSpan;
import com.myenvironment.swing.markdown.MarkdownDocument.MDList;
import com.myenvironment.swing.markdown.MarkdownDocument.Text;
//TODO: finish the markdown view factory
public class MarkdownViewFactory implements ViewFactory{
static abstract class MarkdownView extends View{
public MarkdownView(Element e){
super(e);
}
/**
* A stub, added for compatibility.
* Makes no sense for read-only documents.
* @see View#modelToView(int,Shape,Bias)
*/
public Shape modelToView(int pos,Shape a,Bias b)throws BadLocationException{
return new Rectangle();
}
/**
* A stub, added for compatibility.
* Makes no sense for read-only documents.
* @see View#viewToModel(float, float, Shape, Bias[])
*/
public int viewToModel(float x,float y,Shape a,Bias[]biasReturn){
return 0;
}
}
static abstract class MarkdownContainerView extends CompositeView{
public MarkdownContainerView(Element e){
super(e);
}
public void paint(Graphics g,Shape allocation){
for(int i=0;i * / < b r / > p u b l i c i n t v i e w T o M o d e l ( f l o a t x , f l o a t y , S h a p e a , B i a s [ ] b i a s R e t u r n ) { < b r / > r e t u r n 0 ; < b r / > } < b r / > p r o t e c t e d b o o l e a n i s B e f o r e ( i n t x , i n t y , R e c t a n g l e a l l o c ) { < b r / > r e t u r n ( a l l o c . o u t c o d e ( x , y ) & a m p ; R e c t a n g l e . O U T _ L E F T ) ! = 0 ; < b r / > } < b r / > p r o t e c t e d b o o l e a n i s A f t e r ( i n t x , i n t y , R e c t a n g l e a l l o c ) { < b r / > r e t u r n ( a l l o c . o u t c o d e ( x , y ) & a m p ; R e c t a n g l e . O U T _ R I G H T ) ! =0;
}
protected View getViewAtPoint(int x,int y,Rectangle alloc){
return null;
}
}
static class TextView extends MarkdownView{
public TextView(Text e){
super(e);
}
public float getPreferredSpan(int axis){
FontMetrics fm=getContainer().getFontMetrics(getContainer().getFont());
if(axis==X_AXIS)return fm.stringWidth(((Text)getElement()).text);
else if(axis==Y_AXIS)return fm.getHeight();
else throw new IllegalArgumentException();
}
public void paint(Graphics g,Shape allocation){
Graphics2D g2=(Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g2.setClip(allocation);
Rectangle r=allocation.getBounds();
FontMetrics fm=g2.getFontMetrics();
String text=((Text)getElement()).text;
g2.setColor(getContainer().getForeground());
g2.drawString(text,r.x+(r.width-fm.stringWidth(text))/2,r.y+(r.height+fm.getAscent()+fm.getLeading()-fm.getDescent())/2);
}
}
static class CodeSpanView extends MarkdownView{
public CodeSpanView(CodeSpan e){
super(e);
}
public float getPreferredSpan(int axis){
FontMetrics fm=getContainer().getFontMetrics(getContainer().getFont());
if(axis==X_AXIS)return fm.stringWidth(((CodeSpan)getElement()).text)+fm.getHeight()/3;
else if(axis==Y_AXIS)return fm.getHeight();
else throw new IllegalArgumentException();
}
public void paint(Graphics g,Shape allocation){
Graphics2D g2=(Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g2.setClip(allocation);
Rectangle r=allocation.getBounds();
g2.setColor(new Color(50,50,50,200));
g2.fillRoundRect(r.x,r.y,r.width,r.height,r.height/5,r.height/5);
g2.setStroke(new BasicStroke(r.height/10,1,1));
g2.setColor(Color.BLACK);
g2.drawRoundRect(r.x,r.y,r.width,r.height,r.height/5,r.height/5);
FontMetrics fm=g2.getFontMetrics();
String text=((CodeSpan)getElement()).text;
g2.setFont(new Font(Font.MONOSPACED,Font.PLAIN,getContainer().getFont().getSize()));
g2.setColor(Color.WHITE);
g2.drawString(text,r.x+(r.width-fm.stringWidth(text))/2,r.y+(r.height+fm.getAscent()+fm.getLeading()-fm.getDescent())/2);
}
}
static class MDListView extends MarkdownContainerView{
private float xSpanCached=-1,ySpanCached=-1;
public MDListView(MDList e,ViewFactory f){
super(e);
}
public float getPreferredSpan(int axis){
if(axis==Y_AXIS){
if(ySpanCached==-1){
ySpanCached=0;
for(int i=0;inew CodeSpanView(e);
case MDList e->new MDListView(e,this);
default->new BoxView(elem,BoxView.X_AXIS);
// default->throw new UnsupportedOperationException("No view for "+elem.getName());
};
return v;
}
}
Подробнее здесь: https://stackoverflow.com/questions/796 ... -correctly