Odd behavior of Swing components in a zoomable interface

B

Brent Yorgason

Hello Java experts!

I'm currently working on a project that allows users to mark up an
image of a musical score with annotations such as circles, arrows,
text, etc. Our drawing tools are working great (we used JHotDraw as a
starting point), but I am having difficulties with the text tools,
which use the Swing components JTextPane and JComboBox, and am
particularly having trouble with zooming.

In the interface, the user can create, edit and manually reposition
text boxes (JTextPanes) and labels (JComboBoxes) on the page. When
these elements are not selected, I just draw them on a JPanel, but
when they are selected (and thus become editable), I add the component
to the JPanel using XYConstraints--since they need to stay exactly
where the user has placed them. Here is some code that "selects" a
label (a JComboBox), where labelContainer is the JPanel:

protected void select() {
if (!isSelected) {
this.isSelected = true;
label.setBounds(bounds.x, bounds.y, bounds.width,
bounds.height);
labelConstraints = new XYConstraints(bounds.x, bounds.y,
bounds.width, bounds.height);
labelContainer.add(label, labelConstraints);
}
}

This works great when the zoom level is at 100%. But at any other zoom
level, I see some strange behavior. Part of the swing component is
being drawn in the new scale, but the editable part is still at the
old scale. (And if I try to multiply everything above by the zoom
scale value, the editable part is moved to the right place, but the
"drawn" part has now been scaled twice.) Here is an example of how
this looks:

http://byorgaso.music.indiana.edu/projects/jcombobox.html


I understand that Swing components are actually compound components,
but I don't understand how my scaling values are being applied
correctly to one part of the component and not to the other (the
editable part). And it's bothersome to have two components visually
overlapping on the screen, when I know I've only added a single
component.

Here is the paint code in that class that extends JPanel, showing how
the zoom scale is applied through a transform:

public void paint(Graphics g) {
super.paint(transformGraphics(g, getScale()));
}

private final Graphics transformGraphics(Graphics g, double
currentScale) {
if (currentScale != 1.0) {
Graphics2D g2 = (Graphics2D) g;
g2.transform(AffineTransform.getScaleInstance(currentScale,
currentScale));
}
return g;
}


And just for good measure, here's the entire draw method that is
called to paint the label figure (the JComboBox):

public void draw(Graphics g) {
Graphics2D g2 = (Graphics2D)g;
g2.setFont(font);

// get label
JComboBox label = (JComboBox)getComponent();

// set label bounds
width = getLongestItemWidth(g2) + this.controlWidth + spacer;
height = getCurrentHeight(g2) + spacer;
bounds = new Rectangle(bounds.x, bounds.y, width, height);
int borderWidth = (isSelected)? 1 : 0;
label.setBounds((int)(bounds.x), (int)(bounds.y), width, height);

// set up label appearance
label.setBorder(new LineBorder(Color.black, borderWidth));
label.setMaximumRowCount(15);
label.setOpaque(true);
label.setForeground(textColor);
label.setFont(font);

if (this.isSelected) {
deselect();
select();
}
else {
g2.setColor(label.getForeground());
int yPos = bounds.y + this.getCurrentHeight(g2);
g2.drawString((String)label.getSelectedItem(), bounds.x + 2,
yPos);
}

}

It would be possible to post more code, but there are many classes
involved--I think I've isolated the more relevant parts here.

Has anyone seen anything like this before? What's happening here? Is
there even a way to get these Swing components to zoom well? Any help
at all will be much appreciated. I've been tearing my hair out over it
for a while now and could use an expert's advice.

Thanks again.

Brent
 
M

Mr.Cube

Brent said:
Hello Java experts!

I'm currently working on a project that allows users to mark up an
image of a musical score with annotations such as circles, arrows,
text, etc. Our drawing tools are working great (we used JHotDraw as a
starting point), but I am having difficulties with the text tools,
which use the Swing components JTextPane and JComboBox, and am
particularly having trouble with zooming.

You should checkout 'Jazz'. It is a ZUI which can also zoom
swing components.
It's at :
http://www.cs.umd.edu/hcil/jazz/#
Kees.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,754
Messages
2,569,528
Members
45,000
Latest member
MurrayKeync

Latest Threads

Top