" ABOVE_TOP
Шрифт ITALIC, 18 ");
13. setBorder(BorderFactory.createTitledBorder(
BorderFactory.createEtchedBorder(), "Надпись", TitledBorder.CENTER, TitledBorder.ABOVE_TOP, new Font("Times New Roman", Font.ITALIC, 18)));
JLabel l4 =
new JLabel(" Расположение RIGHT, BELOW TOP ");
14. setBorder(BorderFactory.createTitledBorder(
BorderFactory.createEtchedBorder(), "Надпись", TitledBorder.RIGHT, TitledBorder.BELOW_TOP, new Font("Times New Roman", Font.ITALIC, 18),
Color.red ));
JLabel l5 =
new JLabel(" Расположение CENTER, BOTTOM ");
15. setBorder(BorderFactory.createTitledBorder(
BorderFactory.createEtchedBorder(), "Подпись", TitledBorder.CENTER, TitledBorder.BOTTOM, new Font("Times New Roman", Font.ITALIC, 18),
Color.red ));
add(l1); add(l2); add(l3); add(l4); add(l5); setSize(400, 400);
setDefaultCloseOperation(EXIT ON CLOSE); setVisible(true);
public static void main(String[] args){ new TitBorders();
}
}
Сдвоенные рамки
Рис. 16.4. Сдвоенные рамки |
import java.awt.*; import javax.swing.*; import javax.swing.border.*;
public class CompBorders extends JFrame{
CompBorders(){
super(" Сдвоенные рамки"); setLayout(new FlowLayout());
JLabel l1 = new JLabel(
" CompoundBorder(TitledBorder, TitledBorder) "); l1.setBorder(new CompoundBorder(
BorderFactory.createTitledBorder(
BorderFactory.createEtchedBorder(), "Заголовок",
TitledBorder.CENTER, TitledBorder.ABOVE_TOP,
new Font("Times New Roman", Font.ITALIC|Font.BOLD, 20)),
BorderFactory.createTitledBorder(
BorderFactory.createEtchedBorder(), "Подпись",
TitledBorder.RIGHT, TitledBorder.BOTTOM,
new Font("Times New Roman", Font.ITALIC, 12),
Color.red)
));
JLabel l2 = new JLabel(
" CompoundBorder(BevelBorder.RAISED, BevelBorder.RAISED) ");
12. setBorder(new CompoundBorder(
BorderFactory.createBevelBorder(BevelBorder.RAISED),
BorderFactory.createBevelBorder(BevelBorder.RAISED)
));
JLabel l3 = new JLabel(
" CompoundBorder(BevelBorder.RAISED, BevelBorder.LOWERED) ");
13. setBorder(new CompoundBorder(
BorderFactory.createBevelBorder(BevelBorder.RAISED),
BorderFactory.createBevelBorder(BevelBorder.LOWERED)
));
add(l1); add(l2); add(l3); setSize(400, 400);
setDefaultCloseOperation(EXIT ON CLOSE); setVisible(true);
}
public static void main(String[] args){ new CompBorders();
}
}
Создание собственных рамок
Хотя библиотека Swing предоставляет множество готовых рамок и фабричный класс BorderFactory для их быстрого создания, часто возникает необходимость сконструировать оригинальную рамку.
Для ее создания можно расширить абстрактный класс AbstractBorder, определив хотя бы один конструктор и переопределив методы paintBorder () и getBorderinsets (). Если рамка не прозрачна, то надо переопределить метод isBorderOpaque( ) так, чтобы он возвращал
true.
Свою рамку можно создать, расширив какой-либо класс рамок. В листинге 16.5 приведен пример рамки, расширяющей класс TitledBorder, в заголовок которой можно вставить не надпись, а компонент класса JComponent.
Поскольку класс TitledBorder не является контейнером, его расширение PlaceBorder служит только для рисования границ рамки и для определения места заголовка. Для вставки компонента в заголовок класс PlaceBorder погружается в контейнер PlaceBorderPane, расширяющий JPanel. Компонент помещается в этот контейнер на место, определенное классом PlaceBorder. Все это описано в листинге 16.5 и показано на рис. 16.5.
import java.awt.*; import javax.swing.*; import javax.swing.border.*;
interface BorderConstants{ | ||||||
---|---|---|---|---|---|---|
static | public | final | int | DEFAULT POSITION = 0; | ||
static | public | final | int | ABOVE TOP | = 1; | |
static | public | final | int | TOP | = 2; | |
static | public | final | int | BELOW_TOP | = 3; | |
static | public | final | int | ABOVE BOTTOM | = 4; | |
static | public | final | int | BOTTOM | = 5; | |
static | public | final | int | BELOW BOTTOM | = 6; | |
static | public | final | int | DEFAULT JUSTIFICATION = 0 | ||
static | public | final | int | LEFT = | 1; | |
static | public | final | int | CENTER = | 2; | |
static | public | final | int | RIGHT = | 3; | |
static | public | final | int | LEADING = | 4; | |
static | public | final | int | TRAILING = | 5; | |
static | public | final | int | EDGE SPACING = 2; | ||
static | public | final | int | TEXT SPACING = 2; | ||
static | public | final | int | TEXT_INSET_ | H = 5; } |
public class CompTitledTest extends JFrame implements BorderConstants{ public CompTitledTest(){
super(" Рамка с компонентом");
JLabel lab = new JLabel(" PlaceBorder(JLabel) ", new ImageIcon("middle.gif"), JLabel.LEFT);
PlaceBorderPane pbp =
new PlaceBorderPane(new EtchedBorder(), lab, CENTER, TOP); add(pbp);
setSize(300, 300);
setDefaultCloseOperation(EXIT ON CLOSE); setVisible(true);
}
public static void main(String[] args){
new CompTitledTest();
}
}
class PlaceBorderPane extends JPanel implements BorderConstants{ protected JComponent comp; protected JPanel p; protected PlaceBorder border;
public PlaceBorderPane(){
this(new JLabel(,,3arolnoBOK"));
}
public PlaceBorderPane(JComponent c){ this(null, c, LEFT, TOP);
}
public PlaceBorderPane(Border b, JComponent c, int just, int pos){ super(); comp = c;
border = new PlaceBorder(b, c, just, pos);
setBorder(border);
setLayout(null);
add(comp);
p = new JPanel();
add(p);
}
public JPanel getContentPane(){ return p;
}
public void doLayout(){
Insets insets = getInsets();
Rectangle r = getBounds(); r.x = 0; r.y = 0;
comp.setBounds(border.getComponentRect(r,insets)); r.x += insets.left; r.y += insets.top;
r.width -= insets.left + insets.right; r.height -= insets.top + insets.bottom; p.setBounds(r);
}
class PlaceBorder extends TitledBorder{ public PlaceBorder(JComponent c){ this(null, c, LEFT, TOP);
}
public PlaceBorder(Border b){ this(b, null, LEFT, TOP);
}
public PlaceBorder(Border b, JComponent c){ this(b, c, LEFT, TOP);
}
public PlaceBorder(Border b, JComponent c, int just, int pos){ super(b, null, just, pos, null, null); if (b == null)
border = super.getBorder();
public void paintBorder(Component c, Graphics g,
int x, int y, int width, int height){ Rectangle r = new Rectangle(
x + EDGE_SPACING, y + EDGE_SPACING, width - (EDGE_SPACING * 2), height - (EDGE_SPACING * 2));
Insets bIns = (border != null) ?
border.getBorderInsets(c) : new Insets(0, 0, 0, 0);
Rectangle rect = new Rectangle(x, y, width, height);
Insets insets = getBorderInsets(c);
Rectangle compR = getComponentRect(rect, insets); int diff;
switch (titlePosition){
case ABOVE TOP:
diff = compR.height + TEXT SPACING; r.y += diff; r.height -= diff; break; case TOP:
case DEFAULT_POSITION:
diff = insets.top/2 — bIns.top — EDGE SPACING; r.y += diff; r.height -= diff; break;
case BELOW TOP: case ABOVE_BOTTOM: break;
case BOTTOM:
diff = insets.bottom/2 — bIns.bottom — EDGE SPACING;
r.height -= diff;
break;
case BELOW_BOTTOM:
diff = compR.height + TEXT SPACING; r.height -= diff;
}
border.paintBorder(c, g, r.x, r.y, r.width, r.height);
Color col = g.getColor(); g.setColor(c.getBackground());
g.fillRect(compR.x, compR.y, compR.width, compR.height); g.setColor(col); comp.repaint();
}
public Insets getBorderInsets(Component c, Insets insets){ Insets bIns = (border != null) ?
border.getBorderInsets(c) : new Insets(0, 0, 0, 0);
insets.top = EDGE_SPACING + TEXT_SPACING + bIns.top;
insets.right = EDGE_SPACING + TEXT_SPACING + bIns.right;
insets.bottom = EDGE_SPACING + TEXT_SPACING + bIns.bottom; insets.left = EDGE_SPACING + TEXT_SPACING + bIns.left;
if (c == null || comp == null) return insets;
int h = (comp != null) ? comp.getPreferredSize().height : 0;
switch (titlePosition){ case ABOVE TOP:
insets.top += h + TEXT_SPACING; break; case TOP:
case DEFAULT_POSITION:
insets.top += Math.max(h, bIns.top) — bIns.top; break;
case BELOW TOP:
insets.top += h + TEXT_SPACING; break;
case ABOVE_BOTTOM:
insets.bottom += h + TEXT_SPACING; break;
case BOTTOM:
insets.bottom += Math.max(h, bIns.bottom) — bIns.bottom; break;
case BELOW_BOTTOM:
insets.bottom += h + TEXT_SPACING;
}
return insets;
}
public Rectangle getComponentRect(Rectangle rect, Insets bIns){ Dimension d = comp.getPreferredSize();
Rectangle r = new Rectangle(0, 0, d.width, d.height); switch (titlePosition){ case ABOVE TOP:
r.y = EDGE_SPACING; break; case TOP:
case DEFAULT_POSITION: r.y = EDGE_SPACING +
(bIns.top — EDGE_SPACING — TEXT_SPACING — d.height)/2;
break;
case BELOW TOP:
r.y = bIns.top — d.height — TEXT SPACING; break;
case ABOVE_BOTTOM:
r.y = rect.height — bIns.bottom + TEXT SPACING; break;
case BOTTOM:
r.y = rect.height — bIns.bottom + TEXT SPACING +
(bIns.bottom — EDGE_SPACING — TEXT_SPACING — d.height)/2;
break;
case BELOW_BOTTOM:
r.y = rect.height — d.height — EDGE SPACING;
}
switch (titleJustification) { case LEFT:
case DEFAULTJUSTIFICATION:
r.x = TEXT_INSET_H + bIns.left; break; case RIGHT:
r.x = rect.width — bIns.right -TEXT INSET H — r.width; break;
case CENTER:
r.x = (rect.width — r.width) / 2;
}
return r;
}
Рис. 16.5. Рамка с компонентом JLabel |
Вопросы для самопроверки
1. Какие компоненты Swing можно окружить рамкой?
2. Можно ли окружить рамкой контейнер?
3. Можно ли сделать несколько рамок для одного и того же компонента?
4. Можно ли поменять рамку при наступлении какого-нибудь события?
5. Можно ли поменять цвет рамки при наступлении какого-нибудь события?
6. Можно ли сделать рамку не для всех, а только для одной или нескольких сторон компонента?
7. Можно ли сделать разные рамки для разных сторон компонента?
8. Как меняется рамка при изменении размеров окна?
ГЛАВА 17