Как создать и распределить диагональные полосы на прямоугольнике?

Я хотел бы иметь возможность создавать гистограммы с помощью JFreeChart, которые выглядят примерно так, как показано на следующем рисунке.

желаемый результат

Это очень простая одноцветная гистограмма, но с одной «причудливой» деталью: диагональными полосами. Я думал, что это можно сделать, наложив другую картинку поверх обычной полосы. Эта картинка будет иметь те же размеры, что и полоса, с диагональными белыми полосами и прозрачным фоном. Я не совсем уверен, как это сделать, так как у меня очень мало опыта работы с графическим интерфейсом, но я нашел очень полезная статья, посвященная наложению изображений поверх графики из JFreeChart, так что я совершенно уверен, что смогу вытащить это из.

Но как мне создать диагональные полосы? Я вижу, как я мог бы распределить линии из левого нижнего угла в правый верхний угол, но не линии с заглушками в левом верхнем и правом нижнем углу. Можно ли как-то рисовать за пределами прямоугольника (и не включать его в рисунок)?

edit: после некоторых поисков я не вижу, что мое предложение по наложению изображения с прозрачным фоном будет работать, так как я не могу найти примеров того, как это сделать. С другой стороны, просто рисовать линии на прямоугольнике, вероятно, проще.


person oligofren    schedule 04.08.2011    source источник
comment
Вы хотите, чтобы этот паттерн отображался на столбцах графика или на фоне?   -  person trashgod    schedule 04.08.2011
comment
Я хочу рисовать полосы, а не фон.   -  person oligofren    schedule 05.08.2011


Ответы (2)


Использование градиентной заливки для рисования линий

По совету Trashgod я попытался заполнить фигуру градиентом с острыми краями, чтобы имитировать рисование линий. Это предотвратит множество вычислений и потенциально может быть намного проще. Это работало вполне нормально для толстых линий, но не для более тонких линий. Использование следующего кода создает заливку первого изображения:

    rect.setSpace(spaceBetweenLines);
    Color bg = Color.YELLOW;
    Color fg = Color.BLUE;
    rect.setPaint(new LinearGradientPaint(
            (float) startX, (float) startY, (float) (startX + spaceBetweenLines), (float) (startY + spaceBetweenLines),
            new float[] {0,.1f,.1001f}, new Color[] {fg,fg,bg}, MultipleGradientPaint.CycleMethod.REPEAT)
    );

Попытка нарисовать тонкие линии с помощью градиентной заливки

Рисование линий с помощью графических примитивов

Хотя проще не получилось в моем случае. Более сложный, но для меня более естественный способ сделать это — просто нарисовать линии поверх формы (прямоугольник, круг, ...). При создании второго изображения использовался следующий код. Обратите внимание на использование clip(Shape s), чтобы ограничить рисование линии фигурой внизу. Причина, по которой нельзя просто нарисовать прямоугольник и использовать clip() для ограничения формы, заключается в том, что операция clip() не использует псевдонимы, что приводит к возникновению неровностей. Поэтому я должен сначала нарисовать фигуру, чтобы получить гладкие края, затем установить клип, чтобы предотвратить переполнение в предстоящем рисовании линий, и, наконец, нарисовать линии.

public void paint(Graphics g) {
    Graphics2D g2 = (Graphics2D) g;
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

    g2.setPaint(getBackground());
    g2.fill(getShape());
    g2.setClip(getShape());

    // draw diagonal lines
    g2.setPaint(getLineColor());

    for (int x = (int) this.x, y = (int) (this.y); y - height < (this.y + height + getSpace()); ) {
        g2.drawLine(x, y ,  x + (int) width , y  - (int) width);

        y += getSpace();
    }

Просто рисуйте линии поверх другой фигуры, используя clip(Shape s), чтобы ограничить переполнение

person oligofren    schedule 23.08.2011
comment
Просто было похожее требование и использовался линейный градиент с MultipleGradientPaint.CycleMethod.REFLECT. Никакой коррупции таким образом. - person predi; 21.10.2013
comment
Спасибо, я искал это :) - person Vaisakh N; 12.05.2016
comment
есть ли способ получить этот код в Android или опубликуйте полный код для приведенного выше ответа @oligofren - person Ko Vartthan; 09.06.2017
comment
@KoVartthan Это полный код. Код использует примитивы Swing и AWT. Они не поддерживаются на Android. И я не программировал Java 4 года, так что нет, я не могу сделать твою домашнюю работу. - person oligofren; 09.06.2017
comment
Спасибо @oligofren за ценную информацию - person Ko Vartthan; 09.06.2017

Источник код для BarChartDemo1 показывает, как применить GradientPaint, но вы можете поэкспериментировать с LinearGradientPaint, чтобы получить диагональный эффект.

Я хочу рисовать полосы, а не фон.

Если у вас уже есть подходящее изображение, TexturePaint может быть альтернативой. Оба метода обсуждаются здесь.

person trashgod    schedule 04.08.2011
comment
Спасибо за это, но это кажется более продвинутым, чем то, что необходимо ... ? Я обновил свой вопрос, добавив дополнительную информацию: проблема заключается в рисовании угловых случаев (буквально). - person oligofren; 04.08.2011
comment
Примечание LinearGradientPaint требуется Java 1.6+. - person trashgod; 04.08.2011
comment
Использование заливки линейным градиентом работает, но только для более толстых линий. Как только вы попытаетесь сделать линии ниже 5px, вы начнете получать странные артефакты. Я немного поэкспериментировал с этим, но ничего не вышло... Хотя это было быстрее, чем рисовать много линий! Спасибо за совет. - person oligofren; 23.08.2011
comment
Преди добавил совет, как избежать коррупции, кстати. Однако не проверял (не выполнял Java atm). - person oligofren; 21.10.2013