Reputation: 419
I am using a JSeparator in my java swing application. The normal implementation makes the separator normal line; but what I need is the separator should be dashed(like we create dashed border). Is there any way we can do that?
Thanks
Upvotes: 1
Views: 1120
Reputation: 3420
With a slight modification to trashgod's answer, I found that using paintComponent()
rather than paint()
works very well for me:
Stroke stroke = new BasicStroke(1.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10.0f, new float[] { 5.0f },
0.0f);
JSeparator separator = new StrokedSeparator(stroke);
// Add separator to container
And here's the StrokedSeparator class:
import java.awt.BasicStroke;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Stroke;
import javax.swing.JSeparator;
public class StrokedSeparator extends JSeparator {
private static final long serialVersionUID = 1L;
private Stroke stroke;
public StrokedSeparator() {
this(new BasicStroke(1F), HORIZONTAL);
}
public StrokedSeparator(int orientation) {
this(new BasicStroke(1F), orientation);
}
public StrokedSeparator(Stroke stroke) {
this(stroke, HORIZONTAL);
}
public StrokedSeparator(Stroke stroke, int orientation) {
super(orientation);
this.stroke = stroke;
}
@Override
public void paintComponent(Graphics g) {
Dimension s = getSize();
Graphics2D graphics = (Graphics2D) g;
graphics.setStroke(stroke);
if (getOrientation() == JSeparator.VERTICAL) {
graphics.setColor(getForeground());
graphics.drawLine(0, 0, 0, s.height);
graphics.setColor(getBackground());
graphics.drawLine(1, 0, 1, s.height);
} else // HORIZONTAL
{
graphics.setColor(getForeground());
graphics.drawLine(0, 0, s.width, 0);
graphics.setColor(getBackground());
graphics.drawLine(0, 1, s.width, 1);
}
}
}
Upvotes: 1
Reputation: 205805
To create a custom JSeparator
, you can override the paint()
method of BasicSeparatorUI
, discussed here, and draw the line using a dashed Stroke
, illustrated here.
Addendum: A more familiar approach overrides paintComponent()
, as shown in the accepted answer and encapsulated conveniently in this StrokedSeparator
. The variation below replaces drawLine()
with draw()
using a Line2D
, which takes advantage of the stroke's geometry.
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Stroke;
import java.awt.geom.Line2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSeparator;
import static javax.swing.JSeparator.*;
/**
* @see https://stackoverflow.com/a/74657060/230513
*/
public class StrokeSepTest {
private static final int N = 10;
private void display() {
var f = new JFrame("StrokeSepTest");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
var stroke = new BasicStroke(8.0f, BasicStroke.CAP_BUTT,
BasicStroke.JOIN_MITER, 10.0f, new float[]{5.0f}, 0.0f);
var panel = new JPanel(new GridLayout(0, 1)) {
@Override
public Dimension getPreferredSize() {
return new Dimension(320, 240);
}
};
panel.setBackground(Color.white);
for (int i = 0; i < N; i++) {
Color color = Color.getHSBColor((float) i / N, 1, 1);
panel.add(new StrokedSeparator(stroke, HORIZONTAL, color));
}
f.add(panel);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
// @see https://stackoverflow.com/a/74657060/230513 */
private static class StrokedSeparator extends JSeparator {
private Stroke stroke;
public StrokedSeparator() {
this(new BasicStroke(1F), HORIZONTAL);
}
public StrokedSeparator(int orientation) {
this(new BasicStroke(1F), orientation);
}
public StrokedSeparator(Stroke stroke) {
this(stroke, HORIZONTAL);
}
public StrokedSeparator(Stroke stroke, int orientation) {
super(orientation);
this.stroke = stroke;
}
public StrokedSeparator(Stroke stroke, int orientation, Color color) {
super(orientation);
super.setForeground(color);
this.stroke = stroke;
}
@Override
public void paintComponent(Graphics g) {
var graphics = (Graphics2D) g;
var s = getSize();
graphics.setStroke(stroke);
graphics.setColor(getForeground());
if (getOrientation() == JSeparator.VERTICAL) {
graphics.draw(new Line2D.Double(0, 0, 0, s.height));
} else // HORIZONTAL
{
graphics.draw(new Line2D.Double(0, 0, s.width, 0));
}
}
}
public static void main(String[] args) {
EventQueue.invokeLater(new StrokeSepTest()::display);
}
}
Upvotes: 3
Reputation: 372
You can use the following code snippet to create a dashed line.
import java.awt.Container;
import java.awt.Graphics;
import java.awt.GridLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JSeparator;
public class SeparatorSample {
public static void main(String args[]) {
JFrame f = new JFrame("JSeparator Sample");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container content = f.getContentPane();
content.setLayout(new GridLayout(0, 1));
JLabel above = new JLabel("Above Separator");
content.add(above);
JSeparator separator = new JSeparator() {
private static final long serialVersionUID = 1L;
public void paintComponent(Graphics g) {
for (int x = 0; x < 300; x += 15)
g.drawLine(x, 0, x + 10, 0);
}
};
content.add(separator);
JLabel below = new JLabel("Below Separator");
content.add(below);
f.setSize(300, 100);
f.setVisible(true);
}
}
Upvotes: 2