gpt4 book ai didi

java - 如何在 Blackberry 的 Canvas 上旋转带有文本的圆圈

转载 作者:塔克拉玛干 更新时间:2023-11-01 22:29:54 32 4
gpt4 key购买 nike

如何在 TouchEvent 或 TrackBallMoveEvent 上使用文本旋转圆圈。

  1. 如何创建这种圈子?

    我创建了一个圆并也旋转了它,但它总是从 0 度开始。

  2. 还有其他方法可以创建这种圈子吗?

每个圆圈都有不同的文字,每个圆圈都可以独立移动

enter image description here

最佳答案

所以,这绝对是不完整的,但我认为这是您需要的大部分内容。

限制/假设

  1. 到目前为止,我只实现了触摸处理,因为我认为这比较困难。如果以后有时间,我会回来添加trackball 处理。
  2. 我没有给旋转的圆盘任何动力。用户的手指离开圆盘后,圆盘停止旋转。
  3. 我不确定光盘之间的焦点转换是否 100% 正确。你必须做一些测试。至少他们大部分是对的。
  4. 当您在标题中提到 Canvas 时,我认为这并不意味着您需要它才能利用 J2ME Canvas .使用 RIM UI 库编写 BlackBerry 应用程序几乎是我所做的全部工作。

解决方案

本质上,我创建了一个 Field子类来表示每个光盘。您可以通过传递标签数组来创建字段,这些标签围绕周长、半径和颜色间隔开。在每个 DiscField 中硬编码是文本的边缘插图,它假设圆盘之间存在一定的尺寸差异。您可能应该使它更具动态性。

public class DiscField extends Field {

/** Used to map Manager's TouchEvents into our coordinate system */
private int _offset = 0;
private int _radius;
private int _fillColor;
private double _currentRotation = 0.0;
private double _lastTouchAngle = 0.0;
private boolean _rotating = false;
private String[] _labels;
/** Text inset from outer disc edge */
private static final int INSET = 30;

private DiscField() {
}

public DiscField(String[] labels, int radius, int fillColor) {
super(Field.FOCUSABLE);
_labels = labels;
_radius = radius;
_fillColor = fillColor;
}

protected void layout(int width, int height) {
setExtent(Math.min(width, getPreferredWidth()), Math.min(height, getPreferredHeight()));
}

private void drawFilledCircle(Graphics g, int x, int y, int r) {
// http://stackoverflow.com/a/1186851/119114
g.fillEllipse(x, y, x + r, y, x, y + r, 0, 360);
}

private void drawCircle(Graphics g, int x, int y, int r) {
g.drawEllipse(x, y, x + r, y, x, y + r, 0, 360);
}

protected void paint(Graphics graphics) {
int oldColor = graphics.getColor();
graphics.setColor(_fillColor);
drawFilledCircle(graphics, _radius, _radius, _radius);
graphics.setColor(Color.WHITE);
drawCircle(graphics, _radius, _radius, _radius);

// plot the text around the circle, inset by some 'padding' value
int textColor = (_fillColor == Color.WHITE) ? Color.BLACK : Color.WHITE;
graphics.setColor(textColor);
// equally space the labels around the disc
double interval = (2.0 * Math.PI / _labels.length);
for (int i = 0; i < _labels.length; i++) {
// account for font size when plotting text
int fontOffsetX = getFont().getAdvance(_labels[i]) / 2;
int fontOffsetY = getFont().getHeight() / 2;
int x = _radius + (int) ((_radius - INSET) * Math.cos(i * interval - _currentRotation)) - fontOffsetX;
int y = _radius - (int) ((_radius - INSET) * Math.sin(i * interval - _currentRotation)) - fontOffsetY;
graphics.drawText(_labels[i], x, y);
}

graphics.setColor(oldColor);
}

protected void drawFocus(Graphics graphics, boolean on) {
if (on) {
int oldColor = graphics.getColor();
int oldAlpha = graphics.getGlobalAlpha();
// just draw a white shine to indicate focus
graphics.setColor(Color.WHITE);
graphics.setGlobalAlpha(80);
drawFilledCircle(graphics, _radius, _radius, _radius);
// reset graphics context
graphics.setColor(oldColor);
graphics.setGlobalAlpha(oldAlpha);
}
}

protected void onUnfocus() {
super.onUnfocus();
_rotating = false;
}

protected boolean touchEvent(TouchEvent event) {
switch (event.getEvent()) {
case TouchEvent.MOVE: {
setFocus();
// Get the touch location, within this Field
int x = event.getX(1) - _offset - _radius;
int y = event.getY(1) - _offset - _radius;
if (x * x + y * y <= _radius * _radius) {
double angle = MathUtilities.atan2(y, x);
if (_rotating) {
// _lastTouchAngle only valid if _rotating
_currentRotation += angle - _lastTouchAngle;
// force a redraw (paint) with the new rotation angle
invalidate();
} else {
_rotating = true;
}
_lastTouchAngle = angle;

return true;
}
}
case TouchEvent.UNCLICK:
case TouchEvent.UP: {
_rotating = false;
return true;
}
case TouchEvent.DOWN: {
setFocus();
int x = event.getX(1) - _offset - _radius;
int y = event.getY(1) - _offset - _radius;
if (x * x + y * y <= _radius * _radius) {
_lastTouchAngle = MathUtilities.atan2(y, x);
_rotating = true;
return true;
}
}
default:
break;
}
return super.touchEvent(event);
}

protected boolean trackwheelRoll(int arg0, int arg1, int arg2) {
return super.trackwheelRoll(arg0, arg1, arg2);
// TODO!
}

public int getPreferredHeight() {
return getPreferredWidth();
}

public int getPreferredWidth() {
return 2 * _radius;
}

public String[] getLabels() {
return _labels;
}

public void setLabels(String[] labels) {
this._labels = labels;
}

public int getRadius() {
return _radius;
}

public void setRadius(int radius) {
this._radius = radius;
}

public double getCurrentAngle() {
return _currentRotation;
}

public void setCurrentAngle(double angle) {
this._currentRotation = angle;
}

public int getOffset() {
return _offset;
}

public void setOffset(int offset) {
this._offset = offset;
}
}

包含所有DiscField对象是 DiscManager .它对齐 child DiscFieldssublayout() ,并处理适当的触摸事件委托(delegate)......因为字段重叠,并且触摸在 DiscField 中不在其半径内(即角)的 extent 应由更大的圆盘处理。

   /** 
* A DiscManager is a container for DiscFields and manages proper delegation
* of touch event handling.
*/
private class DiscManager extends Manager {

private int _maxRadius = 0;

public DiscManager(long style){
super(style);

DiscField outerDisc = new DiscField(new String[] { "1", "2", "3", "4", "5", "6" },
180, Color.BLUE);
_maxRadius = outerDisc.getRadius();
DiscField middleDisc = new DiscField(new String[] { "1", "2", "3", "4", "5" },
120, Color.GRAY);
middleDisc.setOffset(_maxRadius - middleDisc.getRadius());
DiscField innerDisc = new DiscField(new String[] { "1", "2", "3", "4" },
60, Color.RED);
innerDisc.setOffset(_maxRadius - innerDisc.getRadius());

// order matters here:
add(outerDisc);
add(middleDisc);
add(innerDisc);
}

protected void sublayout(int width, int height) {
setExtent(2 * _maxRadius, 2 * _maxRadius);

// each disc needs to have the same x,y center to be concentric
for (int i = 0; i < getFieldCount(); i++) {
if (getField(i) instanceof DiscField) {
DiscField disc = (DiscField) getField(i);
int xCenter = _maxRadius - disc.getRadius();
int yCenter = _maxRadius - disc.getRadius();
setPositionChild(disc, xCenter, yCenter);
layoutChild(disc, 2 * _maxRadius, 2 * _maxRadius);
}
}
}

protected boolean touchEvent(TouchEvent event) {
int eventCode = event.getEvent();
// Get the touch location, within this Manager
int x = event.getX(1);
int y = event.getY(1);

if ((x >= 0) && (y >= 0) && (x < getWidth()) && (y < getHeight())) {
int field = getFieldAtLocation(x, y);
if (field >= 0) {
DiscField df = null;
for (int i = 0; i < getFieldCount(); i++) {
if (getField(field) instanceof DiscField) {
int r = ((DiscField)getField(field)).getRadius();
// (_maxRadius, _maxRadius) is the center of all discs
if ((x - _maxRadius) * (x - _maxRadius) + (y - _maxRadius) * (y - _maxRadius) <= r * r) {
df = (DiscField)getField(field);
} else {
// touch was not within this disc's radius, so the one slightly bigger
// should be passed this touch event
break;
}
}
}
// Let event propagate to child field
return (df != null) ? df.touchEvent(event) : super.touchEvent(event);
} else {
if (eventCode == TouchEvent.DOWN) {
setFocus();
}
// Consume the event
return true;
}
}
// Event wasn't for us, let superclass handle in default manner
return super.touchEvent(event);
}
}

最后,使用它们的屏幕:

public class DiscScreen extends MainScreen {

public DiscScreen() {
super(MainScreen.VERTICAL_SCROLL | MainScreen.VERTICAL_SCROLLBAR);

add(new DiscManager(Field.USE_ALL_WIDTH));
}
}

结果

enter image description here

关于java - 如何在 Blackberry 的 Canvas 上旋转带有文本的圆圈,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13656879/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com