Есть ли способ иметь перевернутую область клипа для рисования на Java?

Я хочу заполнить область с помощью Graphics.fillRoundRect(), но я хочу, чтобы прямоугольник в середине не был заполнен.

По сути, учитывая компонент 100x30, я хочу установить отсечение как прямоугольник размером 10,10 размером 80x10, но чтобы заливка закрашивала только область за пределами этого прямоугольника 80x10. Причина в том, что я хочу нарисовать границу из n пикселей с изогнутым контуром, не затрагивая внутреннюю область компонента.

Лучший способ, который я вижу до сих пор, - это обрезать до 10,10 90x10 и выполнить fillRoundRect(), а затем обрезать до 90,10 10x10 и выполнить fillRect(), чтобы заполнить правую сторону, ниже и выше углов.

Если я просто перерисовываю прямоугольник с одной линией, то получаю «пятна» на углах, потому что кривые не совсем соприкасаются (и/или потому что сглаживание влияет на окружающие пиксели).

РЕДАКТИРОВАТЬ: предостережение - мне нужен способ сделать это, который будет работать с J2ME AWT (CDC с личным профилем 1.1), а также с J2SE.


Изменить: у другого похожего вопроса есть ответ Я смог адаптироваться. Код, который работает правильно для моей ситуации, публикуется как самостоятельный ответ.


person Lawrence Dol    schedule 13.08.2009    source источник
comment
Не знаю, почему у этого тега target-c...   -  person Quinn Taylor    schedule 13.08.2009
comment
@Quinn: Спасибо за исправление - я набрал J2ME в поле «Теги», но подозреваю, что при нажатии на вкладку из поля «Теги» на «Редактировать сводку» тег переключался, а я этого не заметил! Я нахожу поведение табуляции в поле тегов очень раздражающим/нелогичным.   -  person Lawrence Dol    schedule 14.08.2009


Ответы (2)


У меня есть похожий ответ и на другой вопрос, а именно использовать полигон в качестве клипа AWT. Может быть, это поддерживается в J2ME? Вам нужно знать границы прямоугольника, который вы хотите исключить, и внешние границы области рисования.

+-------------------+
| clip drawing area |
+---+-----------+   |
|   | excluded  |   |
|   |   area    |   |
|   +-----------+   |
|                   |
+-------------------+

РЕДАКТИРОВАТЬ ИЗ ОП.

Этот ответ сработал для меня, и API поддерживаются в J2ME. Ответ на другой вопрос, по-видимому, имеет одну ошибку - набор координат должен начинаться с точки на внешней левой и внутренней вершине, чтобы создать замкнутый многоугольник. Мой окончательный код, который работал, выглядит следующим образом:

Чтобы создать фигуру отсечения, я использовал этот метод:

static public Shape getOutsideEdge(Graphics gc, Rectangle bb, int top, int lft, int btm, int rgt) {
    int                                 ot=bb.y            , it=(ot+top);
    int                                 ol=bb.x            , il=(ol+lft);
    int                                 ob=(bb.y+bb.height), ib=(ob-btm);
    int                                 or=(bb.x+bb.width ), ir=(or-rgt);

    return new Polygon(
     new int[]{ ol, ol, or, or, ol, ol,   il, ir, ir, il, il },
     new int[]{ it, ot, ot, ob, ob, it,   it, it, ib, ib, it },
     11
     );
    }

который я установил в контексте Graphics, а затем заполнил свой прямоугольник:

Rectangle tmp=new Rectangle(px,py,pw,ph);
gc.setClip(getOutsideEdge(gc,tmp,thickness,thickness,thickness,thickness));
gc.fillRoundRect(px,py,pw,ph,RADIUS,RADIUS);

а затем я создал иллюзию закругленных внутренних углов, нарисовав по одной точке в каждом углу:

gc.setClip(px,py,pw,ph);
gc.drawLine((px   +thickness  ),(py   +thickness  ),(px   +thickness  ),(py   +thickness  ));
gc.drawLine((px+pw-thickness-1),(py   +thickness  ),(px+pw-thickness-1),(py   +thickness  ));
gc.drawLine((px   +thickness  ),(py+ph-thickness-1),(px   +thickness  ),(py+ph-thickness-1));
gc.drawLine((px+pw-thickness-1),(py+ph-thickness-1),(px+pw-thickness-1),(py+ph-thickness-1));
person banjollity    schedule 15.08.2009

Пожалуйста, проверьте мой ответ на этот вопрос. Это очень похоже.

РЕДАКТИРОВАТЬ: вы можете проверить, доступен ли AlphaComposite в j2me. В Java вы можете имитировать клип, изменив составной альфа-режим (я не могу вспомнить, на какой именно, я думаю, его srcIn) и нарисовав изображение с черными и белыми областями. Возможно, вы захотите проверить это.

person Savvas Dalkitsis    schedule 13.08.2009
comment
Да, похоже, что это будет работать для J2SE, но решение также должно работать для J2ME (это требование я изначально не включил, извините). J2ME PP 1.1 не имеет пакета java.awt.geom. Мужчина! это боль, чтобы поддерживать карманные компьютеры! - person Lawrence Dol; 13.08.2009
comment
да, вы должны изменить теги и заголовок тогда. в вопросе, который я предоставил, проверьте ответ не мной. Может быть, это сработает для вас. - person Savvas Dalkitsis; 13.08.2009
comment
+1 за то, что указал мне на аналогичный вопрос, на который был ответ, который я смог адаптировать в рабочее решение. - person Lawrence Dol; 14.08.2009
comment
Краткое примечание: вы использовали 1 дополнительное очко. Точка (ol,it) не нужна, потому что вы можете без проблем перейти из верхнего левого внешнего угла в верхний левый внутренний угол. - person shieldgenerator7; 21.08.2014