Это не совсем то же самое, визуально, но вы можете скрыть кнопку со стрелкой и создать рисунок, который действует как кнопка со стрелкой. TitledPane расширяет Labeled, так что вы можете управлять размещением графики относительно текста через свойство contentDisplay .
Во-первых, спрячьте кнопку со стрелкой в таблице стилей:
.accordion .title > .arrow-button
{
visibility: hidden;
}
В коде вы можете создать метку, действующую в качестве фальшивой кнопки, и установить ее в качестве графического элемента TitledPane. Вся строка заголовка чувствительна к мыши, поэтому интерактивный элемент управления (например, кнопка) не требуется.
Label collapseButton = new Label();
collapseButton.textProperty().bind(
Bindings.when(titledPane.expandedProperty())
.then("\u25bc").otherwise("\u25b6"));
titledPane.setGraphic(collapseButton);
titledPane.setContentDisplay(ContentDisplay.RIGHT);
Хорошая проблема. Я хотел бы попытаться реализовать конкретный тип оболочки итератора, который превращает два диапазона в один диапазон. Что-то вроде:
// compacted syntax for brevity...
template <typename T1, typename T2>
struct concat_iterator
{
public:
typedef std::forward_iterator_tag iterator_category;
typedef typename iterator_traits<T1>::value_type value_type;
typedef *value_type pointer;
typedef &value_type reference;
concat_iterator( T1 b1, T1 e1, T2 b2, T2 e2 )
: seq1( b1 ), seq1end( e1 ), seq2( b2 ), seq2end( e2 );
iterator& operator++() {
if ( seq1 != seq1end ) ++seq1;
else ++seq2;
return this;
}
reference operator*() {
if ( seq1 != seq1end ) return *seq1;
else return *seq2;
}
pointer operator->() {
if ( seq1 != seq1end ) return &(*seq1);
else return &(*seq2);
}
bool operator==( concat_iterator const & rhs ) {
return seq1==rhs.seq1 && seq1end==rhs.seq2
&& seq2==rhs.seq2 && seq2end==rhs.seq2end;
}
bool operator!=( contact_iterator const & rhs ) {
return !(*this == rhs);
}
private:
T1 seq1;
T1 seq1end;
T2 seq2;
T2 seq2end;
};
template <typename T1, typename T2>
concat_iterator<T1,T2> concat_begin( T1 b1, T1 e1, T2 b2, T2 e2 )
{
return concat_iterator<T1,T2>(b1,e1,b2,e2);
}
template <typename T1, typename T2>
concat_iterator<T1,T2> concat_end( T1 b1, T1 e1, T2 b2, T2 e2 )
{
return concat_iterator<T1,T2>(e1,e1,e2,e2);
}
Теперь вы можете использовать:
class X {
public:
template <typename Iter, typename Iter2>
X(Iter b1, Iter e1, Iter2 b2, Iter2 e2 )
: mVec( concat_begin(b1,e1,b2,e2), concat_end(b1,e1,b2,e2) )
{}
private:
vector<Y> const mVec;
};
или (я только что подумал об этом), вам не нужно повторно объявлять ваш конструктор. Заставьте вашего вызывающего абонента использовать вспомогательные функции:
X x( concat_begin(b1,e1,b2,e2), concat_end(b1,e1,b2,e2) );
Я не проверял код, просто набрал его здесь, в верхней части моей головы. Он может скомпилироваться или не получится, может сработать или нет ... но вы можете принять это как отправную точку.
It would probably be best to drop const
(why would you insist on it anyway?).
Otherwise, you have to build a concatenating iterator. It is quite a lot of code, see this thread for more.
Одна из лучших или худших возможностей C ++, в зависимости от вашей точки зрения, заключается в том, что вы можете злоупотреблять ею, когда это необходимо для справиться с работой. В этом случае const_cast является жертвой:
template <typename Iter1, typename Iter2>
X(Iter1 begin1, Iter1 end1, Iter2 begin2, Iter2 end2) : mVec(begin1, end1) {
const_cast<vector<Y>&>(mVec).insert(mVec.end(), begin2, end2);
}
У меня могут быть неправильные детали, я не пытался это скомпилировать. Но это должно дать вам идею.
1) Я хотел бы сохранить const на mVec, чтобы он считался постоянным во всех других методах X
Это любопытное использование const
для переменной-члена. И это бросает вызов хорошему дизайну. По определению, строительство - это процесс, который требует изменения объекта.
Что касается вашего требования сохранять объект неизменяемым - используйте правильную инкапсуляцию. Вы должны использовать функции const
-member для раскрытия любой функциональности, основанной на вашем mVec
, для клиентов вашего класса.
2) Я хотел бы избежать ненужных копий, если это вообще возможно , То есть одно решение состоит в том, чтобы иметь статический метод, который создает неконстантную временную переменную для диапазона 1, вставляет диапазон 2 и возвращает его, и затем определите конкатенационный конструктор для
. Вы должны смотреть на конструкторы перемещения и ссылки на r-значения в целом (обещанная цель C ++ 0x). Прочитайте эту статью .
Ваш статический метод может быть не таким плохим, как вы думаете, в зависимости от оптимизации вашего компилятора. А в C ++ 0x конструкторы перемещения удаляют любое текущее копирование.
Тем временем используйте итератор-обертку. Код, скорее всего, будет не таким плохим, как поток, на который ссылается avakar, поскольку вам нужно всего лишь реализовать итератор ввода .