Как к StackPanel привязать ObservalCollection? Вот так я понимаю нельзя:
Ответ
Прямо к StackPanel привязаться нельзя, у неё нет понятия «источника внутренних элементов». Но для таких целей есть ItemsControl (или производные от него):
Как к StackPanel привязать ObservalCollection? Вот так я понимаю нельзя:
Прямо к StackPanel привязаться нельзя, у неё нет понятия «источника внутренних элементов». Но для таких целей есть ItemsControl (или производные от него):
data = "Hello".encode("utf-8") # перевод в байты
не могу разобраться в байтах... как бы я не старался, Python мне выдает b'Hello'... как мне получить исходные байты этой строки?
Если попробовать с кириллицей, то все получается:
data = "Привет".encode("utf-8") # b'\xd0\x9f\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82'
или я не имею представления о байтах? объясните пожалуйста
Как b'Hello' так и b'\xd0\x9f\xd1\x80...' принадлежат к одному типу bytes
b'Hello' == b'\x48\x65\x6c\x6c\x6f'. Байты, которые соответствуют печатаемым ascii символам (0x20..0x7e), по умолчанию показаны как эти символы в текстовом представлении repr(data) -- синтаксис, используемый для bytes-конcтант в исходном коде Питона (eval(repr(data)) == data).
Использование символов для некоторых байтов вместо шестнадцатеричных кодов может вводить в заблуждение (как в этом случае). Легко получить hexdump, если необходимо
>>> b'Hello'.hex()
'48656c6c6f'
Мотивация по использованию b'Hello' вместо b'\x48\x65\x6c\x6c\x6f' могла быть связана с тем, что многие популярные протоколы такие как HTTP свободно смешивают текст (закодированный в ascii-совместимой кодировке) и двоичные данные. Поэтому использование символов вместо hex-кодов может помочь при отладке.
Недостаток использования b'Hello' вместо b'\x48\x65\x6c\x6c\x6f' состоит в том что люди смешивают понятия текста (Юникодные строки) и двоичных данных (байтов), что ведёт к путанице и в итоге мусору (кракозябрам) в результатах. Что было особенно остро на Питоне 2, где str = bytes. See Stop displaying elements of bytes objects as printable ASCII characters in CPython 3 [python-ideas mailing list (2014)]
Без явного указания кодировки, последовательность байтов (bytes объект) является просто набором чисел. Последовательность байтов становится текстом только, если байты декодированы, используя подходящую кодировку:
unicode_text = bytestring.decode(character_encoding)
Здравствуйте!
Подскажите, пожалуйста, как организовать разработку веб-приложения, а именно, как организовать взаимосвязь между применяемыми технологиями.
Я хочу создать веб-приложение по обмену вещами между пользователями. Приложение пишется на Java + Spring MVC + Spring Security (для авторизации пользователя) + Hibernate с использованием сборщика Maven, а в качестве СУБД используется HSQLDB. Для Представления используется JSP. Сервер приложений - встроенный Jetty, не требующий внешнего веб-контейнера.
Вопросы:
Как сделать так, чтобы проект автоматически собирался и работал на любом ПК с предустановленными JDK и Maven? Что для этого нужно сделать?
Что сделать, чтобы нужная схема данных автоматически создавалась и заполнялась начальными данными при первом запуске веб-приложения?
Это должно происходить именно при первом запуске приложения, а не при каждом его включении.
Расскажите поподробнее про то, как мне организовать доступ к HSQLDB из Hibernate, учитывая требования (1 и 2) и как хранить/упаковать БД и СУБД исходя из этого.
Требуется также написать скрипт сборки проекта с помощью Maven и показать его исходники заказчику. Что в данной ситуации будет скриптом сборки? Maven ведь декларативный сборщик.
Спасибо заранее!
Для этого достаточно использовать maven в качестве билд-системы. Тогда на любой машине с установленными maven и jdk можно будет выполнить
mvn package
и получить артефакт (вероятнее всего вы захотите zip-архив) с вашим продуктом. Вам скорее всего понадобятся maven-shade-plugin и/или maven-assembly-plugin.
Автоматическое создание схемы можно доверить Hibernate (используя параметр hibernate.hbm2ddl.auto=update), но предпочтительнее делать это SQL-скриптом. Если планируются апдейты приложения и схемы данных, стоит задуматься об использовании средств версионирования схемы БД. Например, Flyway умеет проверять при старте версию схемы в БД последовательно накатывать необходимые миграции (SQL-скрипты, обновляющие схему) на БД и заливать исходные данные из XML.
Файл данных БД можно хранить в директории приложения или за её пределами, например, в $HOME/.myapplication/ или в /var в Linux (%APPDATA%/myapplication в случае Windows). Хранение базы данных в отдельной рабочей директории даст ей больше шансов на выживание при удалении и переустановке вашей программы.
Мавеновский pom.xml и будет скриптом сборки. Декларативным скриптом.
Примерно все это можно получить "из коробки", используя Spring Boot. Просто идете на страницу http://start.spring.io, жмете Switch to the full version? заполняете форму и отмечаете флажками пункты:
Web
Security
JPA
HSQLDB
и Generate project в конце.
На выходе у вас будет архив с готовым скелетом приложения c maven-скриптом как раз под ваши нужды. Нужно будет доработать напильником: заменить Tomcat на Jetty и досыпать в зависимости Flyway, например.
На первом скриншоте - то что я вижу в android studio. На втором - то что появляется при запуске программы. Текст находится в layout-е фрагмента. Как избавиться от белой рамки как на втором скрине? Layout имеет свойства match_parent. Заранее спасибо.
Никогда не пользуйтесь предпросмоторщиком, встроенным в IDE - он полон багов и править их, скорее всего, никогда не будут, ибо им никто не пользуется, ибо он не нужен. Отступы, кои вы видите, где-то у вас в разметке. Ищите в коде/разметке активити/фрагмента margin и/или padding. Уберите их и отступы пропадут.
Как правильно реализовать роботу локализованных ресурсов?
Делаю так: создаю новый файл ресурсов strings через ПКМ-New-Valuse и там задаю странну, ну и язык. Получаю уже два файла(правда флаг не тот, но не важно, надеюсь на функционал не влияет).
Имеются такие массивы:
Делаю так:
String[] food = getResources().getStringArray(R.array.food);
И вот вопрос, правильно ли я это делаю? А то проверить не получается.
Вы все делаете правильно. Стоит заметить, что в Android Studio есть встроенный редактор локализации - Translation Editor, который сильно облегчает работу, как по созданию новой локализации, так и редактированию существующей.
Инструмент сам создаст необходимые папки и файлы, вам требуется только выбрать язык и, собственно, заполнить сам перевод в таблице строковых ресурсов.
Иконка редактора - синий глобус, попасть туда можно из визуального редактора разметки, открыв любой Layout или нажав на кнопку-ссылку Open Editor, открыв любой файл строковых ресурсов, так же можно кликнуть правой кнопкой мыши на любом файле строковых ресурсов и выбрать Open Translations Editor
Было скопировано с помощью rsync -avz (или -rvz) с сервера на сервер несколько сайтов, и у многих файлов поменялся владелец и сменились права.
Чтобы восстановить права, первое и единственное, что пришло в голову, это:
На исходном сервере запустить ls -lah /www/sait1 > permis.file
пробежаться таким образом по всем папкам, вложенным тоже.
перекинуть результат на новый сервер, распарсить все, и уже обратным образом, пробегая по папкам, назначить нужные права.
Меня смущает сам метод.
Есть более правильное или другое решение сложившейся проблемы?
Про архивацию через tar не предлагать, про нее знаю, проблема возникла - ее надо решать.
Самое простое и быстрое, что пришло в голову - это сделать на первой машине
# для данных о каталогах
find / -type d -exec stat -c "%n %a %G %U" {} \; | awk '{print "chown "$3":"$4" "$1"; chmod "$2" "$1}' > dirs.txt
# для данный о файлах
find / -type f -exec stat -c "%n %a %G %U" {} \; | awk '{print "chown "$3":"$4" "$1"; chmod "$2" "$1}' > files.txt
полученные файлы переносятся на целевую машину, изучаются, фильтруются по мере надобности. А потом накатываются с помощью bash
bash dirs.txt
bash files.txt
То есть, вначале накатываются данные для каталогов, а только потом для файлов. Иначе может сложиться ситуация, когда накатить права для файлов не получиться, так как нет доступа.
можно было бы теоретически это все в одну команду выполнить, но мне было лень дописывать фильтрацию каталогов "." и "..".
import discord
client = discord.Client()
client.login('email', 'password')
@client.event
def on_message(message):
if message.content.startswith('!hello'):
client.send_message(message.channel, 'Hello was received!')
@client.event
def on_ready():
print('Logged in as')
print(client.user.name)
print(client.user.id)
print('------')
client.run()
Как работают @client.event и как называется подобная конструкция?
Эта конструкция называется декоратором
Действует она следующим образом. Если @decorator - некоторый декоратор, то следующая конструкция
@decorator
def f(args):
# . . .
будет преобразована в такую:
def f(args):
# . . .
f = decorator(f)
То есть, в данном случае декоратор - некоторая функция, преобразующая свой аргумент.
P.S. Декораторы в Python - довольно обширная тема. Если хотите разобраться в ней поподробнее, почитайте 38-ю главу книги
Лутц М.
Изучаем Python, 4-е издание. – Пер. с англ. – СПб.: Символ-Плюс, 2011. – 1280 с., ил.
ISBN 978-5-93286-159-2
Добрый день,
Очень давно в разных система была функция beep - она не имела никаких параметров и просто издавал простейший звук. Есть ли аналоги в Андроид ? И если можно с импортом и всеми плюшками которые нужно добавить. очевидно, что для простого действия в андроид нужны сотни строк кода :) и можно ли сделать вызов стандартного звонка например ? И существует ли вызов звуков по идентификаторам - например "сыграть стандартную мелодию звонка"? Т.е. моя задача издать звук БЕЗ КАКИХ ЛИБО ФАЙЛОВ Идущих вместе с приложением, а все примеры идут - это звук из файла mp3 что мне не подходит.
Пока только несколько дней занимаюсь Андроид, поэтому ничего "само-собой" для меня нет ....
Вот так в виде можно проиграть звуковой эффект:
view.playSoundEffect(android.view.SoundEffectConstants.CLICK);
Но это только звук клика. Если же нужно проиграть уведомление то все несколько сложнее:
try {
Uri notify = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
Ringtone r = RingtoneManager.getRingtone(getApplicationContext(), notify);
r.play();
} catch (Exception e) {
e.printStackTrace();
}
Очередной чисто теоретический вопрос - а как убедиться, что constexpr действительно вычисляется во время компиляции? Похоже, что по крайней мере Visual C++, не сумев справиться с constexpr-функцией, никак об этом не сообщает.
Как паллиатив для целочисленного результата можно применить класс-повторилку, типа
template
и тогда для
constexpr int complexFunc(){...}
результат использовать как
val
Но это и громоздко, и ограниченно пригодно...
constexpr гарантирует что функция может быть вызвана на этапе компиляции, если она вызвана в контексте, в котором разрешены только выражения времени компиляции - параметры шаблона, constexpr переменные, другие constexpr функции, размер массива, целочисленные static const члены которые инициализированы при объявлении, инициализаторы в enum.
По этому достаточно использовать constexpr переменные, тогда они будут вычислены на этапе компиляции:
constexpr int f() { return 42; }
int main() {
constexpr int x = f();
return x;
}
как сделать чтото вроде такой разметки? для этого нужно использовать GridView?
На самый верх ставьте
После добавляйте RelativeLayout в котором поместите:
LinearLayout - внутри его расположите GridView для набора цифр, а
для нижних кнопок используйте RecyclerView если вам нужно скролить
елементы, а если у вас как на скрине статически 8 елементов, то
используйте GridView, для нижней панельки поместите LinearLayout.
Две View для боковых кнопок.
Разбираюсь с апплетами. Написал апплет, который должен сохранять своё состояние. Делаю это с помощью класса Properties. Файл свойств находиться по адресу C:\Users\UserName\.ShapeAppletData\.properties Когда тестирую апплет в IDE (Eclipse) всё работает. Когда запускаю в браузере (Mozilla) появляется исключение InvocationTargetException. Вывел сообщение об ошибке, оно такое:
acess denied ("java.util.PropertyPermission" "user.home" "read")
Почему возникает такая ошибка? Может ли апплет обращаться к файлам на компьютере? Как управлять разрешением на чтение/запись апплетом?
UPD :
Локализовал ошибку. Ошибка возникает на этой строчке кода:
userDir = System.getProperty("user.home");
Sun в свое время постарались сделать технологию апплетов безопасной для конечного пользователя. Обычные Java-апплеты запускаются в песочнице с ограниченными возможностями. Вы можете подписать апплет сертификатом от доверенного издателя и, если пользователь примет сертификат и подтвердит запрос полномочий, запустить его вне песочницы.
В песочнице вам доступны
сетевые подключения на тот же хост и порт, откуда был получен апплет (у апплетов, загруженных с локальной файловой системы, ограничений нет);
загрузка HTML-документов
вызов публичных методов апплетов-соседей по странице;
чтение системных свойств:
java.class.version
java.vendor
java.vendor.url
java.version
os.name
os.arch
os.version
file.separator
path.separator
line.separator
и некоторых других при старте через JNLP.
В песочнице в общем случае вы НЕ можете
обращаться к файловой системе (доступно через JNLP);
запускать процессы;
использовать буфер обмена (доступно через JNLP);
отправлять задания на принтеры (доступно через JNLP);
загружать нативные библиотеки (JNI);
подменять SecurityManager;
создавать альтернативные загрузчики классов;
читать некоторые системные свойства:
java.class.path
java.home
user.dir
user.home
user.name
Имеется задача, построить таблицу, столбцы которой являются полями в классе CustomItem
package com.kolos.Table;
import java.util.Date;
public class CustomItem {
public Integer id;
public String name;
public Date date;
public CustomItem(Integer id, String name, Date date) {
this.id = id;
this.name = name;
this.date = date;
}
}
Класс CustomColumnModel
package com.kolos.Table;
import javax.swing.table.DefaultTableColumnModel;
import javax.swing.table.TableColumn;
import java.lang.reflect.Field;
public class CustomColumnModel extends DefaultTableColumnModel{
public CustomColumnModel(Class tClass) {
for (Field tField : tClass.getDeclaredFields()){
TableColumn tColumn = new TableColumn();
tColumn.setHeaderValue(tField.getName());
tColumn.setModelIndex(getColumnCount());
tColumn.setIdentifier(tField);
tField.setAccessible(true);
this.addColumn(tColumn);
}
}
}
Модель таблицы:
package com.kolos.Table;
import javax.swing.table.AbstractTableModel;
import java.lang.reflect.Field;
import java.util.Date;
public class CustomDataModel extends AbstractTableModel{
private CustomColumnModel columnModel;
private CustomItem[] dataList = new CustomItem[3];
public CustomDataModel(CustomColumnModel columnModel) {
this.dataList = new CustomItem[3];
this.dataList[0] = new CustomItem(1, "Fist", new Date());
this.dataList[1] = new CustomItem(2, "Second", new Date());
this.dataList[2] = new CustomItem(3, "Third", new Date());
this.columnModel = columnModel;
}
@Override
public int getRowCount() {
return this.dataList.length;
}
@Override
public int getColumnCount() {
return this.columnModel.getColumnCount();
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
try {
Field tField = ((Field) columnModel.getColumn(columnIndex).getIdentifier());
return tField.get(dataList[rowIndex]);
} catch (IllegalAccessException e) {
return "IllegalAccessExeption";
}
}
}
Класс CustomTable
package com.kolos.Table;
import javax.swing.*;
public class CustomTable extends JTable{
private CustomDataModel dataModel;
private CustomColumnModel columnModel;
public CustomTable() {
setAutoCreateColumnsFromModel(false);
columnModel = new CustomColumnModel(CustomItem.class);
setColumnModel(columnModel);
dataModel = new CustomDataModel(columnModel);
setModel(dataModel);
}
}
Фрейм:
package com.kolos;
import com.kolos.Table.CustomTable;
import javax.swing.*;
import java.awt.*;
public class MainFrame extends JFrame{
public MainFrame() {
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
this.setSize(new Dimension(800, 600));
this.setLayout(new GridBagLayout());
//create table
JScrollPane scrollPane = new JScrollPane();
CustomTable table = new CustomTable();
scrollPane.setViewportView(table);
this.add(scrollPane, new GridBagConstraints(
0, 0, 1, 1, 1, 1, GridBagConstraints.NORTH, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0
));
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
MainFrame mainFrame = new MainFrame();
mainFrame.setVisible(true);
}
});
}
}
Проблема в том что при перетаскивании столбцов (например 2 -> 0) заголовки переносятся, а значения из модели (получаемые методом getValueAt ) переносятся непонятным образом.
Собственно почему так и как исправить?
Дело в том, что когда вы перемещаете столбцы, они реально меняются местами в списке столбцов ColumnModel, при этом в TableModel.getValueAt координаты ячейки приходят уже пересчитанными в пространство модели (значение поля TableColumn.modelIndex) Поэтому когда вы ставите третью колонку на место первой, для показа первой колонки вызывается getValueAt( rowIndex, 2 ), вы берете у модели столбцов колонку по индексу 2, но туда уже сдвинулась средняя колонка, которая отвечала за вывод имени.
Мне кажется, лучше всего держать получение данных по номеру столбца прямо в модели таблицы. Заведите список Field для доступа к данным, заполните его в конструкторе модели, как вы сейчас делаете в CustomColumnModel, и возвращайте имя колонки в TableModel.getColumnName(int). А TableColumnModel вообще не трогать.
public class CustomDataModel extends AbstractTableModel {
private CustomItem[] dataList = new CustomItem[3];
private List
public CustomDataModel( Class tClass ) {
this.dataList = new CustomItem[3];
this.dataList[0] = new CustomItem(1, "Fist", new Date());
this.dataList[1] = new CustomItem(2, "Second", new Date());
this.dataList[2] = new CustomItem(3, "Third", new Date());
for (Field tField : tClass.getDeclaredFields()){
tField.setAccessible(true);
fields.add( tField );
}
}
@Override
public int getRowCount() {
return this.dataList.length;
}
@Override
public int getColumnCount() {
return this.fields.size();
}
@Override
public String getColumnName( int column ) {
return fields.get( column ).getName();
}
// можно возвращать тип столбца, тогда JTable будет выбирать соотв. TableCellRenderer
// @Override
// public Class getColumnClass( int column ) {
// return fields.get( column ).getType();
// }
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
try {
Field tField = fields.get( columnIndex );
return tField.get(dataList[rowIndex]);
} catch (IllegalAccessException e) {
return "IllegalAccessExeption";
}
}
}
public class CustomTable extends JTable{
private CustomDataModel dataModel;
public CustomTable() {
setAutoCreateColumnsFromModel( true ); // не забудьте вернуть автосоздание
dataModel = new CustomDataModel( CustomItem.class );
setModel( dataModel );
}
}
Либо вы можете в getValueAt искать нужную колонку по совпадению columnIndex и tableColumn.getModelIndex(), или воспользоваться методами jTable.convertColumnIndexToView( columnIndex ) (но нужно держать в модели ссылку на таблицу), или sun.swing.SwingUtilities2.convertColumnIndexToView( columnModel, columnIndex ), которые делают то же самое.
Необходимо дать права только на выполнение данной команды:
INSERT INTO table
SELECT *
FROM OPENROWSET(
'MSDASQL',
'Driver={Microsoft Access dBASE Driver (*.dbf, *.ndx, *.mdx)};DBQ=shara',
'SELECT * FROM table2');
Т.е. что бы члены группы имели доступ только table, могли выполнять команду OPENROWSET - не больше и не меньше.
Не подскажете как дать права правильно или где почитать?
Заранее спасибо за Ваши ответы.
Может быть вам подойдёт такой вариант. Заворачиваем команду в хранимую процедуру:
create procedure [dbo].[ImportProc]
with execute as 'UserName' -- тот у кого есть права на table и OPENROWSET
as
begin
set nocount on;
INSERT INTO [table]
SELECT *
FROM OPENROWSET(...);
end
далее создать роль, дать ей права на выполнение процедуры и добавить нужных пользователей в роль:
USE [DBName]
GO
CREATE ROLE [data_import]
GO
GRANT EXECUTE ON [dbo].[ImportProc] TO [data_import]
GO
ALTER ROLE [data_import] ADD MEMBER [DataImporterUserName]
GO
Если нет, то для использования OPENROWSET нужно давать разрешение уровня сервера ADMINISTER BULK OPERATIONS соответствующему логину:
USE [master]
GO
GRANT ADMINISTER BULK OPERATIONS TO [LoginName]
GO
Плюс в базе нужно отдельно разрешить вставку в таблицу:
USE [DBName]
GO
GRANT INSERT ON [dbo].[table] TO [RoleName]
GO
Как реализовывается такие углы(левый верхний, правый нижний) на CSS?
Таких углов на CSS можно достичь с помощью свойств: border-{top,right,left,bottom}
div, body { margin: 0; padding: 0 }
div {
height: 200px;
background: green;
}
div:after {
content: '';
position: absolute;
left: 0;
top: 0;
border-top: 30px solid white;
border-right: 30px solid green;
}
div:before {
content: '';
position: absolute;
right: 0;
top: 170px;
border-bottom: 30px solid white;
border-left: 30px solid green;
}
Добрый день. Возобновил изучение платформы android. Возник такой вопрос. Есть два куска кода, вот собственно первый:
public void runTimer(){
final Handler handler = new Handler();
final TextView timerView = (TextView)findViewById(R.id.time_view);
handler.postDelayed(new Runnable(){
@Override
public void run() {
int hours = seconds%3600;
int minutes = (seconds%3600)%60;
int secs = seconds%60;
String time = String.format("%d:%02d:%02d",hours,minutes,secs);
timerView.setText(time);
if(isStarting){
seconds++;
}
}
}, 1000);
}
а вот второй:
public void runTimer(){
final TextView timerView = (TextView)findViewById(R.id.time_view);
final Handler handler = new Handler();
handler.post(new Runnable(){
public void run(){
int hours = seconds%3600;
int minutes = (seconds%3600)%60;
int secs = seconds%60;
String time = String.format("%d:%02d:%02d",hours,minutes,secs);
timerView.setText(time);
if(isStarting){
seconds++;
}
handler.postDelayed(this, 1000);
}
});
}
Проблема в том что они должны, как я понимаю, работать одинаково, но работает только пример под номером 2. Кто знает почему так?
1 фрагмент кода вызывается ровно 1 раз. Он вызывается через 1 секунду с помощью handler.postDelayed(..., 1000) , отрабатывает и всё.
2 фрагмент кода вызывается сразу методом handler.post и в конце своей работы вызывает handler.postDelayed(this, 1000); т.е. вызывает сам себе через 1 секунду.
А в целом рекомендую ещё посмотреть на класс CountDownTimer, который делает в принципе тоже самое, но "из коробки".
Дано:
Файл с паролями, коий не надо заливать на GitHub.
В .gitignore этот файл прописан и в студии помечен серым цветом.
Проблема:
При коммите сей файл отмечен и выделен в списке файлов для коммита:
Вопрос:
Что таки произойдёт при коммит->пуш? Файл сохранится на GitHub и будет всем доступен или просто в истории коммитов будет значится как добавленный в проект но существовать физически будет только на моей машине из-за добавления в gitignore?
P.S.
т.к. в файле пароли и явки пробовать сам опасаюсь(
Удалось решить проблему удалив файл из проекта, сделав коммит без него и добавив его снова.
После этих манипуляций файл перестал появляться в списке файлов для коммита.
Видимо надо сначала составлять .gitignore а потом уже только добавлять в проект игнорируемые файлы.
Согласно ссылке @Yura Ivanov, для тех, кто умеет в командную строку достаточно выполнить такую команду для игнорирования файлов, добавленных до изменения .gitignore
git rm --cached
Создал я локальный репозиторий у себя на компьютере:
cd /path/to/git/repo/
git init --bare --shared
В другом месте тоже инициализировал, с которым работал так, напрямую:
cd /path/to/my/project/
git init
echo "Helo" >> hello.txt
git add .
git commit -m "Init"
Вот теперь я хочу в свой локальный репозиторий сделать пуш:
git remote add origin /path/to/git/repo/
git push origin master
Все хорошо, все отлично. Если запустить эту команду в другой директории, он мне все скопирует, то есть сделает то, что я ожидаю:
cd /path/to/test/dir/
git clone /path/to/git/repo/
Теперь я хочу:
Все свои собранные коммиты запушить на свежий, только что созданный репозиторий в bitbucket.org.
Иметь возможность пушить как на битбакет, так и в локальный репозиторий
Что мне нужно сделать, чтобы добиться такого результата?
P.S. Отвечая на вопрос, зачем мне нужен локальный репозиторий. Мне нужно всегда иметь на компьютере копию проекта с учетом всех gitignore. Даже тогда, когда у меня нет интернета. Если есть возможность провернуть это без создания локального репозитория, можете дать совет. Но вопрос, как запушить все коммиты на битбакет и не видеть постоянные сообщения Everything up-to-date и другие, не смотря на то, что на компе у меня лежит целая куча нужных мне коммитов, остается открытым
когда вы сделали git init, вы уже создали локальный репозиторий. он находится в под-каталоге .git
файлы же, которые вы создали в этом каталоге (/path/to/my/project/), а затем с помощью git add и git commit «добавили в репозиторий», на самом деле представляют собой лишь рабочую копию содержимого репозитория.
репозиторий может быть и без рабочей копии. создаётся такой репозиторий при использовании опции --bare у команд git clone, git init. фактически вы получаете в таком репозитории то же содержимое, что и в каталоге .git у репозитория с рабочей копией
поэтому создавать ещё одну локальную копию репозитория, как сделали вы в каталоге /path/to/git/repo/, нет необходимости. всё содержимое репозитория, все коммиты, вся история — доступны в любой из копий git-репозитория и без доступа к интернету. и коммиты в эту копию репозитория вы можете делать без доступа к интернету.
а как сделать вторую (третью, десятую) копию репозитория на каком-нибудь удалённом сервере, вы уже знаете:
$ git remote add ...
$ git push ...
о том, как одной командой git push отправить изменения сразу в несколько репозиториев, написано, например, здесь и здесь. и по-русски: Отправить изменения в несколько репозиториев одной командой push
Пытаюсь запустить spring-boot с использованием страницы greeting.html в папке src/main/resources/templates, но вместо страницы выводится просто текст greeting
@RestController
@EnableAutoConfiguration
public class Example {
@RequestMapping("/greeting")
public String greeting() {
return "greeting";
}
public static void main(String[] args) throws Exception {
SpringApplication.run(Example.class, args);
}
}
Собираю мавеном. Результат одинаковый, что из IDE, что из командной строки.
В чем может быть проблема?
Для решения проблемы нужно было добавить зависимость на thymeleaf, изменить html шаблон соответствующим образам (т.е. на корректным образом сформированную thymeleaf-шаблон) и поменять аннотацию @RestController (является сочетанием аннотаций @Controller и @ResponseBody) на @Controller (обозначает что данный класс является котроллером в модели Spring MVC).
При работе со Spring Boot не рекомендуется использовать jsp, так как jsp не будет работать со спринг бутом (только из варника).
Метод showResults - показывает AlertDialog, метод endOfGame - закрывает Aktivity. При показе AlertDialog появляется на пол секунды, и потом исчезает, как оставить его на экране?
private void stopGame() {
showResults();
endOfGame();
}
private void showResults() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.results);
builder.setMessage("Message");
builder.setNegativeButton(R.string.OK, null);
builder.create().show();
}
В метод stopGame() приложение попадает из AsyncTask, возможно где-то здесь ошибка?
private class TimerAsyncTask extends AsyncTask
public TimerAsyncTask(int time) {
this.time = time;
}
@Override
protected Void doInBackground(Void... params) {
while (time > 0) {
SystemClock.sleep(1000);
time--;
publishProgress(time);
}
return null;
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
chronometrView.setText(values[0].toString());
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
stopGame();
}
}
Присоединюсь к комментарию Abrog Petrovich.
В методе showResults() вы вызываете билдер для создания диалогового окна.
Строчка AlertDialog.Builder builder = new AlertDialog.Builder(this); по сути говорит, что билдер будет использовать данное активити (инфлейтить его, использовать стиль и тд), те вы создаете диалоговое окно относительно данного активити.
Но вы в endOfGame(); я так понимаю закрываете это активити, и закрывается диалог - соответственно. В голову приходят срау два способа решения:
1.Действительно, переместите закрытие Activity те ваш метод endOfGame(); в AlertDialog, пусть срабатывает при его закрытии например, ну или сделайте логику Да/Нет. Дайте пользователю принять выбор.
2.Можете создавать Диалоговое окно в новом Acitivity, или открывать новое Actvity в форме диалогового окна, вариантов здесь много, но нужно видеть что происходит в методе endOfGame().
Есть фрагмент кода:
public String getInstallPath () {
String commandLinePath = CommandLineSettings.getSettings().getInstallDir();
if (commandLinePath != null && !commandLinePath.isEmpty()) {
return commandLinePath;
} else {
return getProperty("installPath", OSUtils.getDefInstallPath());
}
}
Здесь есть обращение к getSettings(), который определен как:
@Getter
private static CommandLineSettings settings;
static {
settings = new CommandLineSettings();
}
При попытке получить объект появляется ошибка Cannot resolve method 'getSettings()'. Как это можно поправить? Почему происходит такая проблема?
Не знаю что делает аннотация @Getter, поэтому предложу обычный вариант написания геттера для статического поля класса:
private static CommandLineSettings settings;
static {
settings = new CommandLineSettings();
}
public static CommandLineSettings getSetting() {return settings;}
Пользоваться также как вы и пытались:
CommandLineSettings settings = CommandLineSettings.getSettings();
Пытаюсь использовать message_queue. Собственно код ничего не делает, кроме вызова конструктора.
Часть build log
/usr/bin/ld: obj/Debug/main.o: неопределённая ссылка на символ «pthread_condattr_setpshared@@GLIBC_2.2.5»
//lib/x86_64-linux-gnu/libpthread.so.0: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
using namespace boost::interprocess;
int main()
{
message_queue(open_or_create,"message_queue" ,100 ,100);
}
Что происходит?
.../libpthread.so.0: error adding symbols: DSO missing from command line
вот тут советуют добавить опцию
-lpthread
к опциям компилятора.
для того, чтобы скомпилировать ваш пример, мне пришлось добавить первой строкой:
#include
и передать компилятору опции -lrt -lpthread. тогда программа test из файла test.cpp компилируется удачно:
$ CPPFLAGS="-lrt -lpthread" make test
g++ -lrt -lpthread test.cpp -o test
описанная же вами ошибка легко воспроизводится при удалении опции -lpthread
$ CPPFLAGS="-lrt" make test
g++ -lrt test.cpp -o test
/usr/bin/ld: /tmp/cc8fR82D.o: undefined reference to symbol 'pthread_condattr_setpshared@@GLIBC_2.2.5'
//lib/x86_64-linux-gnu/libpthread.so.0: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
Пример: из 0xAABBCCDD получить 0x00DDCCBB
Решил задачу так:
MOV EAX, [EAX]; //инициализация
MOV ECX, EAX;
SHR ECX, 16
MOV DH, $00;
MOV DL, AL;
SHL EDX, 16;
MOV DH, AH;
MOV DL, CL;
MOV EAX, EDX;
Можно ли улучшить этот код?
ОС: win32
MOV EAX, [EAX] ; EAX=0xAABBCCDD XOR EBX, EBX ; BL=0x00 XCHG AH, BL ; EAX=0xAABB00DD BL=0xCC ROR EAX, 16 ; EAX=0x00DDAABB MOV AH, BL ; EAX=0x00DDCCBB
Есть код для Android,цель выводить имя месяца:
day_of_month = (TextView)findViewById(R.id.day_of_month);
day_of_week = (TextView)findViewById(R.id.day_of_week);
String month_s = String.format("%1$tB",new Date());
String day_s = String.format("%1$tA",new Date());
month.setText(month_s);
day_of_week.setText(day_s);
Все хорошо,кроме падежа месяца:он выводиться как Марта,Февраля,Сентября и т.д,то есть в родительном падеже.Как вывести в именительном:Март,Февраль,Сентябрь?
Благодаря ответу код приобрёл такой вид:
SimpleDateFormat format = new SimpleDateFormat("yyyy;LLLL;dd;EEEE");
String date_string = String.format("%s",format.format(new Date()));
String[] date_array = date_string.split(";");
year.setText(date_array[0]);
month.setText(date_array[1]);
day_of_month.setText(","+date_array[2]);
day_of_week.setText(date_array[3]);
По-моему, через String.format - никак. С API 9 можно воспользоваться SimpleDateFormat с параметром "L" (stand-alone month):
SimpleDateFormat format = new SimpleDateFormat( "LLLL" );
System.out.printf( "sdf: %s%n", format.format( new Date() ) ); // sdf: Март
Аналогичный параметр для дня недели - "c", хотя для русского языка это не важно.
template
[Error] no match for 'operator*' (operand types are 'A' and
'B')
Почему не работает оператор приведения?
UPD
Оказывается, вот это компилится
#include
template
template
int main()
{
B
Так что, возможно, проблема с другим связана
Вся проблема заключается в ADL (Argument Dependent Lookup), если же вы operator* реализуете отдельно от класса, то проблема будет решена:
template
template
template
template
template
int main()
{
B
Пояснение
Операторы, определенные в теле класса, не видны извне класса и могут быть найдены только при помощи ADL (поиска по типам аргументов).
Оператор приведения типа тут просто не успевает сработать, т.к. компилятор даже не знает что экземпляр класса A необходимо привести к классу B (да и вообще, какому-либо классу), а реализация данного оператора находится именно внутри класса B
Например, браузер при первой загрузке закэшировал файлы CSS и JS. Позже я изменил содержимое этих файлов и загрузил их на сервер. Как указать браузеру, что файлы были обновлены, чтобы он перегрузил их и обработал?
Можно обновить страницу с помощью клавиш Ctrl+F5, однако не будем же мы вешать объявления на сайте, чтобы все пользователи обновляли страницу указанным способом.
Традиционно к URL файла, на который есть ссылка, добавляется какое-нибудь уникальное значение в query, например, script.js?1337. Формат запроса значения не имеет, так как веб-серверы игнорируют его для файлов.
Надо отметить, что в большинстве случаев это избыточно. Протокол HTTP предоставляет множество возможностей по настройке кэширования. Обычно запрос на статический файл уходит всегда, но при этом клиент (браузер то есть) может сообщить, что файл уже закэширован, и указать версию (дату, метку). В случае, если на сервере файл не обновился, сервер отдаст пустой ответ, говоря клиенту пользоваться кэшированной версией. Если файл обновился, то сервер отошлёт новый файл.
К сожалению, есть всякие глупые кэширующие прокси, криво настроенные браузеры и прочий шибко умный софт, который мешает нормальному функционированию HTTP согласно стандарту. Поэтому такие костыли и необходимы.
Имеется несколько компьютеров с 3g модемами, на них должен быть запущен apache(порт 8080). Как проверить что apache запущен на каждом из них. Visual studio 2013 c#.
Попробуйте (для каждого IP-адреса)
WebRequest request = WebRequest.Create("http://A.B.C.D:8080/");
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
if (response == null || response.StatusCode != HttpStatusCode.OK)
{
// failed
}
response.Close();
Если нет гарантий, что адреса буду всегда одни и те же, можно использовать какую-нибудь службу DDNS. Тогда вместо IP-адресов можно использовать FQDN.
Есть элементы подобные этому:
Ваш код:
select("[^trRandom]");
select("div[^trRandom]");
Производит поиск по названию атрибута, который начинается на trRandom, а вам нужно по значению атрибута class по такому принципу: [attr^=valPrefix]
Вот так: select("[class^=trRandom]");
select("div[class^=trRandom]");
Подробней: http://jsoup.org/apidocs/org/jsoup/select/Selector.html
Странная работа оконных функций min, max в ms sql 2012 при обработке null–значений. 2 запроса
select max(q1) OVER(PARTITION BY q2 order by q1) from
(
select null as q1, 1 as q2, 0 as q3
union
select 11, 1, 1
union
select null, 1, 1
) a
select max(q1) OVER(PARTITION BY q2) from
(
select null as q1, 1 as q2, 0 as q3
union
select 11, 1, 1
union
select null, 1, 1
) a
Результат первого
NULL
NULL
11
Второго
11
11
11
Казалось бы причём тут в функциях min max order by...
Microsoft SQL Server 2012 - 11.0.5058.0 (X64)
May 14 2014 18:34:29
Copyright (c) Microsoft Corporation
Enterprise Edition: Core-based
Licensing (64-bit) on Windows NT 6.1 (Build 7601: Service Pack
1)
и
Microsoft SQL Server 2014 - 12.0.2000.8 (X64)
Feb 20 2014 20:04:26
Copyright (c) Microsoft Corporation
Enterprise Edition (64-bit) on
Windows NT 6.3 (Build 9600: )
Немного модифицируем ваш запрос:
select max(q1) OVER(PARTITION BY q2 order by q3),
min(q1) OVER(PARTITION BY q2 order by q3),
sum(q3) OVER(PARTITION BY q2 order by q3),
max(q1) OVER(PARTITION BY q2),
sum(q3) OVER(PARTITION BY q2)
from
(
select null as q1, 1 as q2, 0 as q3
union
select 12, 1, 1
union
select 11, 1, 2
) a
Результат:
NULL NULL 0 12 3
12 12 1 12 3
12 11 3 12 3
Видно, что у выражений без ORDER BY берется требуемое значение для всего окна, а для предложений с сортировкой - берется накопленное на данный момент значение в порядке сортировки.
Теперь открываем документацию, раздел "Общие примечания":
Если предложение ORDER BY не указано, то для рамки окна используется весь раздел. Это относится только к тем функциям, которым не требуется предложение ORDER BY. Если предложение ROWS или RANGE не указаны, а указано предложение ORDER BY, то в качестве значения по умолчанию для рамки окна используется RANGE UNBOUNDED PRECEDING AND CURRENT ROW
Собственно в документации сказано именно то, что мы увидели в результате запроса. Если order by указан, то функции к которым это применимо, рассматривают окно он начала раздела заданного partition by до текущей строки.
Я использую в приложении шаблон Navigation Drawer Activity и у меня возникли несколько вопросов по поводу правильного использования его и фрагментов в целом.
Т.к. все страницы (назову фрагменты, открываемые из бокового меню так) приложения - фрагменты в одной активити, то я лишаюсь возможности использовать Intent для переключения активиностей?
Как реализовать открытие фрагмента (какой-то страницы) по какому-то действию из другого фрагмента? Сделать интерфейс, напримерIFragmentAction, со всеми событиями, которые могут послать фрагменты, реализовать его у активити и вызывать эти методы из фрагментов? А в них уже делать транзакции? Это правильно?
Аналогично, если нужно по действию во фрагменте показать фрагмент, не явлюящийся "страницей" - надо делать аналогично, через активити? Или можно сделать транзакцию прямо из фрагмента (в настоящий момент сделал так, но кажется это немного неправильно)
Если нужен режим для планшета, где некоторые фрагменты не открываются поверх старых, а расположены рядом - надо создать новый layouyt еще одну активити, реализующую интерфейс, но с другим поведением? Или это не самый правильный подход?
Как правильно вернуть результат из DialogFragment? Я реализовывал интерфейс у фрагмента, который вызывал этот диалог, через который диалог устанавливал нужные значения. Кажется, не лучший подход.
Столкнулся с такой проблемой:
Если после нескольких смен фрагментов пользователь переходит через боковое меню на другую страницу - он видит несколько наложившихся активностей. Если просто сделать белый фон - задняя активность все равно останется кликабельной.
Как правильно сделать переходы между активностями, чтобы не возникало таких проблем и чтобы это было правильно?
Отвечу на всю историю примерным кодом.
Пусть Ваш NavigationDrawer содержит кастомный адаптер для списка. При нажатии в списке на элемент вы к примеру получите йд нужного фрагмента, пусть это будет int, Но лучше строка. Получаем TAG Фрагмента.
private String getTagById(int tagId) {
String tag = null;
if (Frag1.TAG_ID == tagId) {
tag = Frag1.TAG;
} else if (Frag2.TAG_ID == tagId) {
tag = Frag2.TAG;
}
return tag;
}
Дальше в роль вступает участок кода для работы с фрагментами. В нем мы узнаем совпадает ли активный фрагмент с выбранным, если не совпадает мы сделаем detach активного, проверим открывали ли ранее выбранный и выполним replace или attach
private void showFragment(String tag) {
String oldTag = mSelectedTag;
mSelectedTag = tag;
final FragmentManager fm = getSupportFragmentManager();
final FragmentTransaction ft = fm.beginTransaction();
final Fragment oldFragment = fm.findFragmentByTag(oldTag);
final Fragment fragment = fm.findFragmentByTag(tag);
if (oldFragment != null && !tag.equals(oldTag)) {
ft.detach(oldFragment);
}
if (fragment == null) {
ft.replace(R.id.container, getContentFragment(tag), tag);
} else {
if (fragment.isDetached()) {
ft.attach(fragment);
}
}
ft.commit();
}
Этот кусок кода отдает нужный фрагмент по тагу.
private Fragment getContentFragment(String tag) {
Fragment fragment = null;
if (Frag1.TAG.equals(tag)) {
fragment = new Frag1();
} else if (Frag2.TAG.equals(tag)) {
fragment = new Frag2();
}
return fragment;
}
А вот так все запускаем:
@SuppressWarnings("StatementWithEmptyBody")
@Override
public boolean onNavigationItemSelected(MenuItem item) {
showFragment(getTagById(item.getItemId()));
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
Для чего нужны сессии в PHP?
Да, с их помощью можно сделать аутентификацию менее ресурсоемкой (якобы обходится без БД).
Но, при аунтефикации мы всё равно должны делать запрос к БД, хотя бы для того чтобы убедится, не забанен ли пользователь.
Да, сессии служат для передачи каких-то глобальных параметров.
Но, для этого есть методы подобные include и похожие.
Так зачем же тогда нужны сесии?
Вступлением, я хочу Вам задать встречный, риторический вопрос: зачем в js нужны LocalStorage если есть Cookie?
Странно, но вы не упомянули о куках, хотя, по моему мнению, сессии больше всего общего имеют как раз с ними (на самом деле сессии связаны с куками). И уж совсем непонятно, при чем тут include. Это конструкция которая включает код файла.
Сессия в PHP, по умолчанию, хранится в файловой системе сервера. Но это настраиваемо (при чем логику можете сами задать, если хотите, можно и в базе сессии хранить). Сессия будет возвращать определенный массив для каждого запроса, с определенным сессионным ключом. Ключ сессии хранится в куках, помечается сессионным (время жизни 0) и обычно обновляется после закрытия браузера, т.е. данные перестают быть доступными. Но тут есть исключения, например, Google Chrome. Он, почему-то, ключ сохраняет. Сессии, в отличие от кук, хранятся на сервере (только ключ на клиенте), пользователь не имеет прямого доступа, и в поля можно записывать больше информации чем в куках.
Про базы данных: да, проверка пользователя нужна через базу данных, но есть куча других мест, где сессии можно было бы использовать. Нарпимер - корзина в интернет магазине.
Или давайте представим, что у Вас многошаговая форма на 900 полей, и Вам нужно сохранять данные, даже если пользователь ушел со страницы - сессии тут помогут.
Для чего используется static в операторе :: ?
return static::Find($id);
Ключевое слово static используется для позднего статического связывания, т.е. в классах унаследованных от этого можно будет определить свой статический метод Find() и будет вызываться именно он, а не метод текущего класса. Если вы вместо static укажите self, то будет вызван статический метод Find() текущего класса, даже если в унаследованных классах вы определите собственные статические методы Find().
Так как статические методы принадлежат не объектам, а классам - приходится разруливать ситуацию с их переопределением при помощи отдельных ключевых слов.
Как запретить использование конструктора копирования и оператора присваивания? Т.е. так чтобы классом мог пользоваться только другой класс, а в main нельзя было создать экземпляр этого класса.
В main компилироваться не должен, а в другом классе это было бы возможно:
A a;
A a(b);
A a=b;
Можно решить данную проблему с использованием дружественного класса:
class myClassClose{
myClassClose(); //конструктор по умолчанию
myClassClose(const myClassClose&); //конструктор копирования
myClassClose(myClassClose&&); //конструктор перемещения
myClassClose operator = (const myClassClose&) const; //оператор присваивания
myClassClose operator = (myClassClose&&) const; //оператор присваивания с перемещением
public:
friend class myClass;
};
class myClass{
myClassClose a;
public:
myClass(){}
};
Есть ListView в котором есть 1000 элементов и при быстрой прокрутке списка возникает эффект как у колеса машины, сначала в одну сторону прокрутка идет , а потом обратно, хотя по факту он в нужную сторону крутится, каким образом можно избавиться от этого эффекта? Возможно для большого количества элементов в списке нужен другой адаптер ?
ListViewAdapter.java
public class ContactListAdapter extends BaseAdapter {
private Context context;
private static final String TAG = "ContactListAdapter";
ArrayList
private ViewHolder preHolder;
private ViewHolder secondHold;
public ContactListAdapter(Context context, ContactList contactList) {
this.context = context;
list = contactList;
layoutInflater = (LayoutInflater) this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public void setList(ArrayList
public static class ViewHolder {
private View rootView;
private TextView tvName;
private TextView tvInitials;
private ImageView ivAvatart;
private ImageView ivStatus;
private RelativeLayout relativeLayoutParent;
private RelativeLayout relativeLayoutMain;
private RelativeLayout onlineButtonContainer;
private RelativeLayout timeoutButtonContainer;
private RelativeLayout relativeLayout_exit_buuton_conteiner;
private RelativeLayout relativeLayout_icon_phone;
private String contactName;
private boolean isShow;
private ContactCaling contactCaling;
}
@Override
public View getView(final int position, final View convertView, final ViewGroup parent) {
final ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
holder.rootView = convertView;
LayoutInflater layoutInflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
holder.rootView = layoutInflater.inflate(R.layout.main_contact_list_item, null);
holder.tvName = (TextView) holder.rootView.findViewById(R.id.textView_contact_name);
holder.tvInitials = (TextView) holder.rootView.findViewById(R.id.textView_contact_initials);
holder.ivAvatart = (ImageView) holder.rootView.findViewById(R.id.imageView_contact_avatar);
holder.ivStatus = (ImageView) holder.rootView.findViewById(R.id.imageView_status);
holder.relativeLayoutParent = (RelativeLayout) holder.rootView.findViewById(R.id.relativeLayout_parent);
holder.relativeLayoutMain = (RelativeLayout) holder.rootView.findViewById(R.id.relativeLayout_main);
holder.onlineButtonContainer = (RelativeLayout) holder.rootView.findViewById(R.id.relativeLayout_call_button_container);
holder.relativeLayout_icon_phone = (RelativeLayout) holder.rootView.findViewById(R.id.relativeLayout_icon_phone);
holder.timeoutButtonContainer = (RelativeLayout) holder.rootView.findViewById(R.id.relativeLayout_call_busy_button_container);
holder.relativeLayout_exit_buuton_conteiner = (RelativeLayout) holder.rootView.findViewById(R.id.relativeLayout_exit_buuton_conteiner);
/**-------------Item listener---------------**/
holder.relativeLayoutParent.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (preHolder == null || (secondHold != null && secondHold.equals(holder))) {
if (MyApplication.isOnline()) {
int buttonTranslation = -holder.onlineButtonContainer.getLayoutParams().width + 2;
holder.onlineButtonContainer
.animate()
.translationX(buttonTranslation)
.setDuration(350);
secondHold = null;
} else {
int buttonTranslation = -holder.timeoutButtonContainer.getLayoutParams().width + 2;
holder.timeoutButtonContainer
.animate()
.translationX(buttonTranslation)
.setDuration(350);
secondHold = null;
}
}
if (preHolder != null) {
if (MyApplication.isOnline()) {
int translate = preHolder.onlineButtonContainer.getLayoutParams().width;
preHolder.relativeLayoutMain
.animate()
.translationX(0)
.setDuration(350);
preHolder.onlineButtonContainer
.animate()
.translationX(translate)
.setDuration(350);
} else {
int translate = preHolder.timeoutButtonContainer.getLayoutParams().width;
preHolder.relativeLayoutMain
.animate()
.translationX(0)
.setDuration(350);
preHolder.timeoutButtonContainer
.animate()
.translationX(translate)
.setDuration(350);
}
}
if (preHolder != null) {
preHolder = null;
} else {
preHolder = holder;
}
secondHold = holder;
}
});
holder.isShow = false;
holder.rootView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.contact = (Contact) getItem(position);
holder.contactName = holder.contact.getDisplayName();
holder.tvName.setText(holder.contactName);
setIcons(position, holder);
return holder.rootView;
}
@Override
public int getCount() {
return list.size();
}
@Override
public Object getItem(int position) {
return list.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
}
Нужно сделать так, что бы частота обновления экрана была различна с частотой прокручивания элементов списка.
Наверно можно уменьшить скорость скрола ListView
listView.setFriction(ViewConfiguration.getScrollFriction() * FRICTION_SCALE_FACTOR)
Есть объект типа dynamic, в который упакован некий MyClass. Если я к экземпляру (dynamic) обращаюсь и запрашиваю свойство Property1, например, то может ли сам экземпляр отловить это обращение, даже если этого свойства в нем нет, или запрос свойства при этом идет через тип?
Самый простой способ отлавливания обращений к членам класса — унаследоваться от DynamicObject
Если вам достаточно словаря, ключи которого ведут себя как свойства, то есть ещё ExpandoObject
Есть некий generic класс
public class GenericClass
Ну и экземпляр класса используется как DataContext. Тогда для вызова из xaml будет такая разметка
и вернет она текст "qwer".
Вопрос, а можно ли какими либо ухищрениями избавиться от квадратных скобок? Вот есть класс DataView, как там это реализовано?
Нашел решение. Класс public class GenericClass
Я не выложу дословный код, потому что не имею его под рукой. Могу лишь из памяти набросать его основу
Класс:
public class ViewModel
public ViewModel(T obj)
{
_source = obj;
}
// далее идет реализация интерфейса. Все методы сделаны идентично, я приведу пример одного
public AttributeCollection GetAttributes()
{
return TypeDescriptor.GetAttributes(_source);
}
}
Класс еще не готов. Нужно еще наследовать INotifyPropertyChanged и предусмотреть мониторинг свойств модели или иные способы изменения свойств из кода. Но это совсем другая история )
Что имеется?
Имеется таблица такого вида
+----+--------------+-------+--------------+
| id | product_name | count | warehouse_id |
+----+--------------+-------+--------------+
| 1 | Puperproduct | 10 | 1 |
| 2 | Puperproduct | 15 | 2 |
| 3 | Puperproduct | 12 | 3 |
+----+--------------+-------+--------------+
Что нужно получить?
Нужно получить макс и мин количество товаров с ихними складами.
+-----+---------------+-----------+------------------+-----------+------------------+
| id | product_name | min_count | min_warehouse_id | max_count | max_warehouse_id |
+-----+---------------+-----------+------------------+-----------+------------------+
| 1 | Puperproduct | 10 | 1 | 15 | 2 |
+-----+---------------+-----------+------------------+-----------+------------------+
Что у меня получилось?
Получилось:
select
id
, product_name
, min(count) as min_count
, max(count) as max_count
from table
group by product_name
+----+--------------+-----------+-----------+
| id | product_name | min_count | max_count |
+----+--------------+-----------+-----------+
| 1 | Puperproduct | 10 | 15 |
+----+--------------+-----------+-----------+
Как взять ид складов? Количество записей около 800К. Mysql 5.5
Собираем в одну строку count дополненный, скажем, до 10 символов и соответствующий ему warehouse_id, берем от этой строки min/max и потом из этого вырезаем склад обратно и преобразуем в числовой вид:
select id, product_name,
max(count) as max_count, min(count) as min_count,
substr(min(concat(lpad(count,10,'0'),warehouse_id)),11)+0 min_warehouse_id,
substr(max(concat(lpad(count,10,'0'),warehouse_id)),11)+0 max_warehouse_id
from table
group by product_name
При создании базы возникает следующая ошибка:
andrey@asus:~/project/odnogrupniki$ rake db:create:all
FATAL: Peer authentication failed for user "odnogrupniki"
логи целиком: ТУТ
databse.yml:
default: &default
adapter: postgresql
encoding: unicode
pool: 5
timeout: 5000
username: 'odnogrupniki'
password: '1111'
development:
<<: *default
database: odnogrupniki
test:
<<: *default
database: odnogrupniki_test
production:
<<: *default
database: odnogrupniki_production
в Gemfile добавлял: gem 'pg'
Bundle - выполнял
andrey@asus:~/project/odnogrupniki$ psql --version
psql (PostgreSQL) 9.5.1
Пользователя создавал так:
postgres@asus:/home/andrey/project/odnogrupniki$ createuser odnogrupniki -P -S -R -D
Enter password for new role:
Enter it again:
Локально можно настроиться на работу по peer athentication, но для этого в базе данных должен быть пользователь с таким же именем, какой у подключающегося логин в операционной системе. Для разработки это можно настроить максимально быстро на чистом дистрибутиве.
Чтобы ActiveRecord подключался, удостоверяясь только с помощью учётной записи подключающегося через Unix domain socket, то надо убрать логин, пароль и хост из настроек подключения. Совсем. А сделать "себя" суперпользователем в БД на свежеустановленном PostgreSQL (когда пользователь там всего один, postgres) можно в одну команду:
sudo -u postgres createuser --superuser $(whoami)
\______________/ \______________________________/
Притворившись Создать суперпользователя с
postgres именем, выведенным командой whoami
А дальше обычное rake db:create и прочее.
Плюсов у такого подхода хватает:
Работает с настройками по умолчанию: установил, сделал себя-администратора и вперёд
Учётные данные ни в какой момент не существуют в рабочем дереве
На "боевом" сервере так делать не стоит, но это уже совсем другая история...
Например, на сайте есть спец ссылки aliexpress://product/desc?productId=32309744542 при переходе по которым открывается приложение AliExpress. Если мне нужно добавить GET параметр, например, aliexpress://?param=32309744542 он должен быть передан в ссылку, так: http://m.aliexpress.com?param=32309744542 (в обычном браузере). В приложении невозможно просмотреть ссылку поэтому я хочу узнать, будет ли это работать?
На андроиде схема такая:
В манифесте для нужной активити добавляется IntentFilter, в коем указывается на нажатия на какие ссылки нужно реагировать.
В этой активити, уже в коде через Intent вытаскивается ссылка, коей запущено приложение. Ссылка разбирается на части и выстраивается логика её обработки.
В манифесте примерно так (сначала идёт пример обычных ссылок на сайт, потом типа такой как вы в вопросе написали):
В активити получаем ссылку так:
Uri data = getIntent().getData();
Log.d("ЛОГ", "Uri data: " + data);
Здравствуйте, скажите, пожалуйста, какя разница между конструкторами:
int age;
string name;
Man (int age, string name){
age=age;
name=name;
}
Man (int age, string name){
this.age=age;
this.name=name;
}
В первом вы не установите значение у полей класса. Это называется сокрытие переменных(Variable shadowing). Хороший ответ о сокрытии на SOen
Есть приложение (чат) в котором нужно сделать отображение сообщений в виде списка. Но не просто отобразить списком view-хи с текстом, view могут содержать в себе еще картинки + view сами по себе могут быть разными. При простом отображении элементов выбор пал бы на ListView. Но нужно не только их отображать но и иметь возможность их видоизменять, анимировать и т.д. Попробовав сделать список через ScrollView я столкнулся с проблемой что ScrollView притормаживает, как я понял потому что элементы не пересоздаются, а хранятся в памяти! Вопрос: каким образом лучше реализовать нужную задачу, лично я склоняюсь к ScrollView, так как с ним по идее должно быть проще работать, но как можно решить проблему притормаживания, может есть какие то механизмы?
p.s. может кто то знает как подобные задачи реализован в Viber, VK и остальные messanger
Не используйте ScrollView, со временем он будет тормозить еще больше, по мере добавления View. Используйте RecyclerView, примеров в сети достаточно. В нем вы можете указывать любые View в зависимости от объекта, который вам нужно показать. В добавок "ячейки" в RecyclerView которые ушли за экран, дестроятся. это экономит память.
UPD
У RecyclerView можно переопределить метод getItemViewType(), и в зависимости от возвращаемого значения в onCreateViewHolder() в можете подставлять нужную View
Я решаю задачу о нахождении лидера (leader election)
Это чисто алгоритмическая задача, у которой есть 2 формы: однонаправленное кольцо и двунаправленное. Для представления данных я создал свой собственный класс для списка, закрученного в кольцо. То есть у меня два алгоритма, по одному для каждой формы задачи.
public abstract class MyAbstractRoundList {
protected int size;
protected Agent[] arr = new Agent[1];
protected int index = 0;
public boolean isEmpty() {
return size == 0;
}
public int size() {
return size;
}
public void add(Agent agent) {
if (size >= arr.length) {
Agent[] temp = arr;
arr = new Agent[temp.length * 2];
System.arraycopy(temp, 0, arr, 0, temp.length);
}
arr[size++] = agent;
}
// и дальше еще много методов
Далее я создаю наследников этого класса для однонаправленного режима и для двунаправленного. Реализации в них конечно различаются. Далее, у меня есть класс:
public class LeaderElection {
public static void solve(MyAbstractList list, int i) {
if (i == 0) {
list.initiateStartState();
} else {
list.setMessages();
}
}
}
В нем у меня решение для однонаправленного режима. И есть похожий класс с решением для двунаправленного, но реализации конечно тоже различаются. Что бы не прописывать в клиентском коде
if(isOneDirectMode()){
LeaderElection.solve();
{
if(isBiDirectMode()){
BiLeaderElection.solve();
}
Я мог бы так же создать абстрактный класс для решения и его наследников и пользоваться полиморфизмом (так я и делаю для списков). Но вот тут и возникает проблема: у меня получаются параллельные иерархии наследования. Если появится новый режим я должен буду добавить новый класс подкласс MyAbstractRoundList и новый подкласс решения. Можно как то избавиться от этого? Я вижу только один способ: Можно было бы сделать в MyAbstractRoundList абстрактный метод solve() и реализовывать его в подклассах каждого режима так как это требуется для конкретного режима. Но это плохо, потому что тогда у меня подклассы MyAbstractRoundList будут не только хранить данные, но и решать задачу. То есть выполнять 2 функции.
Они не параллельны. Изменения в одной иерархии никак не влекут за собой изменения в другой иерархии.
Если появится новый режим я должен буду добавить новый класс подкласс
MyAbstractRoundList и новый подкласс решения. Можно как то избавиться
от этого? Я вижу только один способ: Можно было бы сделать в
MyAbstractRoundList абстрактный метод solve() и реализовывать его в
подклассах каждого режима так как это требуется для конкретного
режима.
Решение задачи - это поведение. Поведение лучше описывать интерфейсами.
public interface Solver {
void solve(MyAbstractList list, int i);
}
...
public class LeaderElection implements Solver {
...
public class BiLeaderElection implements Solver {
...
public class MultiTreadingLeaderElection implements Solver {
У вас отдельная иерархия наследования классов, отвечающих за хранение данных, и отдельная иерархия классов, отвечающих за решения. Это нормально. Если появится новый вид хранения (новый тип списка), вы добавите новый класс-наследник MyAbstractRoundList. Это никак не связано с решениями, новый класс может использоваться и существующими решениями. Если потребуется добавить новый способ решения, вы добавите новый класс, реализующий интерфейс Solver, и это не обязательно должно отразиться на иерархии классов для хранения.
При таком подходе у вас всегда будет работать код solver.solve(abstractList, i);, если в переменную solver положить объект любого класса, реализующего интерфейс Solver, а в переменную abstractList - любой объект класса-наследника MyAbstractRoundList, и самое главное - этот код не придется менять при добавлении новых классов, как и должно быть с точки зрения ООП.
UPD. Есть данные, есть поведение. В рамках класса поля описывают данные, методы - поведение. Например, я руковожу бригадой роботов. Одни из них могут строить, другие - переносить, третьи - разрушать, четвертые - поливать. Робот-строитель, например, может принести себе стройматериал, но только в небольшом количестве, таким образом, он может и строить, и носить. А робот-носитель - только носить. И если вдруг поступает задача срочно разгрузить вагон стройматериалов, то мне надо собрать всех роботов, умеющих носить. И мне плевать, что это за роботы. Хоть робот-поливалка. Если может носить - пусть идет носить. Я просто выберу роботов с нужным мне поведением, и буду уверен, что они смогут сделать то, что мне надо.
public interface Carrier {
void carry(); //нести
}
public interface Builder {
void build(); //построить
}
public interface Destroer {
void destroy(); //сломать
}
public class RobotBuilder extends Robot implements Builder, Carrier {
public void carry() {
}
public void build() {
}
}
public class RobotDestroer extends Robot implements Destroer {
public void destroy() {
}
}
public class RobotCarrier extends Robot implements Carrier {
public void carry() {
}
}
Имеется тестовое задание:
Дан файл вида
operand1;operand2;operation;result
operand1;operand2;operation;result
operand1;operand2;operation;result
operand1;operand2;operation;result
Каждая строка описывает арифметическое действие.
operand1 и operand2 - операнды, целые числа
operation - арифметическое действие + - / *
result - результат операции operation над operand1 и operand2
В файле могут содержаться любые значения полей
Требуется
Реализовать юнит (JUnit) тесты арифметических действий.
Каждое действие должно выглядеть в отчете как отдельный тестовый сценарий
Конец задания
Я понимаю, как написать тесты JUnit, но не понимаю, что именно тестируется в данном случае.
Правильно ли я считаю, что нужно сначала написать код, который парсит переменные, 4 функции для разных арифметических действий, а потом проверять с помощью JUnit корректность работы функций на основании тестовых равенств в файле
?
Прошу вас высказать свое понимание задачи.
Я бы написал скрипт (хотя, если там несколько строк, то можно и ручками), который на основании исходного файла нагенерирует Java файл с тестами. То есть, на каждую строку исходного файла будет генерировать что то вида
@Test
public void test1() {
int actual = operand1 operationoperand2;
int expect = result;
assertEquals(expect , actual);
}
ну м конечно несколько строк "обвязки" для всего этого, что бы модуль был "компилируемый".
В более навороченном виде я бы добалял проверку на 0 для operand2 если operation равно /
UPD
Вот на коленке на perl сделать за минут 5, для собеседования считаю самое оно
#!/usr/bin/perl
use strict;
use warnings;
print '
import junit.framework.*;
public class JavaTest extends TestCase {
protected void setUp(){
}
';
my $i = 1;
while (my $line = <>) {
chomp $line;
my ($op1, $op2, $oper, $result) = split /;/, $line;
print <<"ONE_TEST";
\@Test
public void test$i() {
int actual = $op1 $oper $op2;
int expect = $result;
assertEquals(expect, actual);
}
ONE_TEST
$i += 1;
}
print "}
";
Как изменить цвет кнопок в АлертДиалоге?
В разметке диалога задаю
android:background="@color/background_window"
все, кроме кнопок подсвечивается серым цветом
пробую вот так:
dialog.getButton(DialogInterface.BUTTON_POSITIVE).setBackgroundColor(ContextCompat.getColor(MyApplication.getAppContext(), R.color.background_window));
приложение падает при открытии диалога
Заранее спасибо
Решение выше перекрашивает только бакграунд у кнопок
По сути ответ на вопрос был закоментирован в ответе выше
Перед открытием диалога вставил строчку:
dialog.getWindow().setBackgroundDrawableResource(R.color.background_window);
и все заработало:
Странно, что строка в разметке не устанавливает бэкграунд для панели кнопок